Править: После реализации James Hopkin' предложение, я все еще получаю предупреждения "недопустимого имени 'пустой указатель'", который намного лучше, чем те странные символы. Затем я возвратился, и прочитайте документ библиотеки снова, и оказывается, что для той конкретной функции, это - аргумент, должен иметь еще один элемент непустой строки, чем размер aNames. Та дополнительная строка имеет некоторую другую цель. После добавления еще одной строки хорошо работает код. Это - весь мой отказ, и я очень сожалею.
Исходное сообщение:
Привет,
Это - мое первое сообщение поэтому быть хорошим. Я искал на этом форуме и погуглил, но я все еще не могу найти ответ. Эта проблема беспокоила меня больше дня, поэтому дайте мне некоторую справку.Спасибо.
Я должен передать вектор строки к нечто библиотечной функции (символьная константа *константа *константа). Я не могу передать &Vec [0], так как это - указатель на строку. Поэтому я имею массив и передаю c_str () к тому массиву. Следующее является моим кодом (aNames, вектор строки):
const char* aR[aNames.size()];
std::transform(aNames.begin(), aNames.end(), aR,
boost::bind(&std::string::c_str, _1));
foo(aR);
Однако кажется, что это вызывает некоторое неопределенное поведение:
Если я выполняю вышеупомянутый код, то функциональные нечто бросают некоторые предупреждения о запрещенных символах ('èI' blablabla) в площади.
Если я печатаю площадь перед функциональным нечто как это:
std::copy(aR, aR+rowNames.size(),
std::ostream_iterator<const char*>(std::cout, "\n"));
foo(aR);
Затем все прекрасно. Мои вопросы:
Преобразование вызывает неопределенное поведение? Если так, почему?
Что корректный путь состоит в том, чтобы передать вектор строки к нечто (символьная константа *константа *константа)?
Поскольку foo
принимает только указатель, мое безумное предположение состоит в том, что для него требуется массив с завершающим NULL. Выделите дополнительный элемент для aR
и присвойте ему NULL.
Я предлагаю следующее:
std::vector<const char*> c_strings;
c_strings.reserve(aNames.size() + 1);
std::transform(
aNames.begin(), aNames.end(),
std::back_inserter(c_strings),
boost::bind(&std::string::c_str, _1)
);
c_strings.push_back(0);
foo(&c_strings[0]);
Мне кажется, это правильно. c_str создает массив символов с завершающим нулем, который является постоянным до следующей операции неконстантной строки. Вы храните указатели c_str в массиве const char *.
Я не специалист по ускорению, поэтому проблема может быть там, но я предполагаю, что ваши строки в векторе имеют кодировку, несовместимую с кодировкой, ожидаемой в функции foo.
Проверьте свой код с точки зрения кодирования.
my2c
Попробуйте следующее:
std::vector<char*> arr(aNames.size()+1);
for(size_t i = 0; i < aNames.size(); ++i)
arr[i] = aNames[i].c_str();
arr[arr.size()-1] = NULL; // just in case
foo(&arr[0]);