Почему вектор, возвращаемый моей функцией C , содержит мусорные значения в вызывающем объекте?

#c #vector #stl #folly

#c #вектор #stl #глупость

Вопрос:

Я создал простую программу на C для чтения и маркирования входных данных из cin. Однако, хотя токены в моей вспомогательной функции верны, токены в вызывающей функции (main) являются мусорными значениями.

Например, если я ввожу «a b c» в качестве входных данных, вектор токенов в моей вспомогательной функции (get_input_tokens) содержит «a», «b», «c», но вектор токенов в main содержит «?», «?», «».

Я понимаю, что вектор должен быть возвращен по значению вызывающему объекту, поэтому в вызывающем объекте (main) должна быть создана новая копия вектора, идентичная исходному вектору. Кто-нибудь сможет дать мне несколько идей о том, почему это происходит?

 #include <folly/String.h>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

vector<folly::StringPiece> get_input_tokens() {
    string input;
    getline(cin, input);   // Enter in "a b c"
    
    vector<folly::StringPiece> tokensVec;
    folly::split(" ", input, tokensVec);

    // Print tokensVec - prints out "a", "b", "c"
    for (int i=0; i<tokensVec.size(); i  ) {
        cout << tokensVec[i] << endl;
    }

    return tokensVec;
}

int main(int argc, char *argv[]) {
    auto tokensVec = get_input_tokens();

    // Print tokensVec - prints out "?", "?", ""
    for (int i=0; i<tokensVec.size(); i  ) {
        cout << tokensVec[i] << endl;
    }
    return 0;
}
  

Ссылка на folly::split:https://github.com/facebook/folly/blob/master/folly/String.h#L403 .

Комментарии:

1. Что такое folly::split ? Кажется, это наиболее подходящая функция для создания вектора. Пожалуйста, добавьте это в свой вопрос.

2. Можете ли вы поделиться с нами реализацией folly / String? Насколько мне известно, компиляторы решают, как его вернуть, и для выполнения этой задачи можно использовать конструктор перемещения или конструктор копирования. Таким образом, проблема, вероятно, либо в конструкторе копирования, либо в конструкторе перемещения класса folly / String.

3. Спасибо за быстрый ответ! Ах, извините, забыл добавить это — это библиотечная функция из folly (Facebook библиотека C с открытым исходным кодом), которая выполняет то же самое, что и функция разделения Python (т. Е. разбивает входную строку на разделитель). Ссылка: github.com/facebook/folly/blob/master/folly/String.h#L403 .

4. Спасибо за быстрый ответ! Конечно, вот реализация: github.com/facebook/folly/blob/master/folly/String.h#L403 . Я вижу, это имеет смысл — в таком случае позвольте мне взглянуть на конструкторы перемещения и копирования для folly::StringPiece.

Ответ №1:

Это потому, что a StringPiece содержит указатели на строку, частью которой он является.
В вашем случае это input , который уничтожается при возврате функции и делает все StringPiece значения недействительными.

Вам нужен другой тип для токенов.
Я не знаком с folly, но если создатели не потеряли сюжет полностью, std::string должно сработать.

Комментарии:

1. Спасибо за объяснение! Я не знал, что StringPiece содержит указатели на другую строку — имеет смысл, что если он указывает на локальную переменную, то это было бы недопустимо вне области видимости этой переменной. Я пытался с помощью std:: string, но получаю эти ошибки: ` Неопределенные символы для архитектуры x86_64: «folly::makeConversionError (folly::ConversionCode, folly::Range<char const*>)», на которые ссылается: std::__1::enable_if<!(std::is_same<folly::Range<char const*>, std:: __1::basic_string` Но я создам новый вопрос для этого, поскольку это другая проблема.