У меня есть функция C++ 11, вызывающая вызовы против унаследованной функции C. Я подумал, что было бы хорошо создать рабочие потоки (используя std::thread
, который затем передаст переменные функции C. Однако, казалось бы, если поток слишком долго ждет выполнения, то указатели тогда больше не указывают на допустимые места в памяти .Почему значения необработанных указателей перезаписываются/выпадают из области?
Пример (замкнуто для краткости/читаемости, и, очевидно, не код продукции, но воссоздает вопрос):.
//The C function
void c_func(const char* str1, const char* str2, const char* str3){
printf("My strings str1: %s, str2: %s, str3: %s\n", str1, str2, str3);
}
...
//C++ calling the function from numerous threads
std::vector<std::thread> threads;
std::vector<std::vector<std::string>> bar;
...
for (auto const& foo : bar)
{
threads.push_back(std::thread(c_func, foo[0].c_str(), foo[1].c_str(), (foo[0] + foo[1]).c_str()));
}
в распечатке будет распечатай мусор в разные случайные моменты времени После некоторого экспериментирования, я заметил, что это делает не происходит, когда я изменяю функцию «C», чтобы использовать std::string
вместо const char*
. Однако это изменение означало бы тонну перезаписи на наследство код ... который я бы предпочел не делать ...
Есть ли способ разрешить этот тип многопоточного вызова без указателей, указывающих на мусор, если поток не выполняется вовремя? Или я застрял с переписыванием устаревшего кода, чтобы переместить его на C++ ...
Вы выдаете указатели, которые действительны только для времени жизни 'std :: string', из которого они пришли, а затем весело продолжайте делать то, что вы делали в этом потоке, предположительно отбрасывая некоторые из этих 'std: : string's по пути. Это принципиально нарушено, никоим образом не вокруг. На самом деле это не совсем так, как хранить 'char *' в обычной структуре данных, отбрасывая '' '' '' '' '' '' '' '', а затем выбирая 'char *' s, откуда вы их сохранили. Объедините свои жизни вместе. – delnan
@ delnan Gotcha, спасибо за вклад ... Это то, что я подозревал, но не хотел в это верить. –
он сломан даже без потоковой передачи, '(foo [0] + foo [1]). C_str();' будет возвращать мусор, потому что временная строка будет уничтожена после полной оценки выражения. –