为什么原始指针值被覆盖/超出范围

Ben*_*ent 1 c++ multithreading pointers

我有一个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()));
    }
Run Code Online (Sandbox Code Playgroud)

打印输出将在不同的随机时间打印出垃圾.经过一些实验,我注意到当我改变"C函数" std::string而不是使用时,这不会发生const char*.但是,这种改变意味着对遗留代码进行大量重写......我宁愿不这样做......

有没有办法允许这种类型的多线程调用,如果没有及时执行线程,指针就会指向垃圾?或者我坚持重写遗留代码将其移动到C++ ...

rat*_*eak 7

因为c_str()不会阻止字符串被清理.在函数返回并清理bar之后,foo字符串也会被清除,这可能是在线程启动之前.

你应该传递实际的std::string(可能是一个包装,然后char*在调用之前解压缩func)或者确保在join()编辑所有线程之前不清除字符串.


小智 7

这里线程的核心问题是父线程会在这些指针的另一端对内存进行处理,使它们无效.

你需要做的是std::string进入每个线程.不是引用,不是指针,而是副本.现在每个线程都拥有自己的字符串副本,它将通过堆栈和析构函数的魔力自动清理.

现在,您可以调用c_str()每个字符串副本以获取对该线程有效的指针,而不是在不同的范围内进行清理.