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

时间:2014-11-19 19:22:04

标签: 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()));
    }

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

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

2 个答案:

答案 0 :(得分:7)

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

你应该传递实际的std::string(可能是一个包装,然后在调用char*之前提取func)或者确保字符串在你之前没有得到清理join()编辑了所有主题。

答案 1 :(得分:7)

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

您需要做的是将std::string传递到每个帖子中。不是引用,不是指针,而是副本。现在每个线程都拥有自己的字符串副本,它将通过堆栈和析构函数的魔法自动清理。

现在你可以在每个字符串副本上调用c_str()来获得一个对该线程有效的指针,而不是在不同的范围内清理。