将指向临时std :: string的指针传递给另一个线程

use*_*399 0 c++ multithreading

考虑下面的C ++程序

#include <iostream>
#include <thread>
#include <string>

std::string getString() {
    return "hello world";
}

void printString(const char* s)
{
    std::cout << s << std::endl;
}

int main()
{       
    std::thread T(printString, getString().c_str());

    T.join();

    return 0;

}
Run Code Online (Sandbox Code Playgroud)

调用getString()将返回一个临时变量std::string,该值getString().c_str()是一个指向临时堆栈变量的指针。

由于每个线程都有自己的堆栈(但共享堆),因此将指针指向主线程上的字符串传递给某个线程T在理论上不行吗?

为什么此代码会编译并运行以进行打印hello world?还是我遇到某种未定义的行为?

编辑:

如果程序看起来像这样(没有线程)怎么办

#include <iostream>
#include <thread>
#include <string>

std::string getString() {
    return "hello world";
}

void printString(const char* s)
{
    std::cout << s << std::endl;
}

int main()
{       
    printString(getString().c_str());                
    return 0;

}
Run Code Online (Sandbox Code Playgroud)

Nat*_*ica 5

还是我遇到某种未定义的行为?

那正是发生的情况。从返回的字符串getString仅有效,直到扩展结束

std::thread T(printString, getString().c_str());
Run Code Online (Sandbox Code Playgroud)

这意味着printString您将拥有一个指向不再有效的数据的指针。您可能会得到它包含的内容,否则可能会发生其他事情。访问指针是未定义的行为,因此您得到的任何结果都是“正确的”。


如果您更改getString

const char * getString() {
    return "hello world";
}
Run Code Online (Sandbox Code Playgroud)

和创建线程像

std::thread T(printString, getString());
Run Code Online (Sandbox Code Playgroud)

那样就可以了,因为它"hello world"具有静态的存储期限,因此它将在程序的剩余生命周期中有效