当C++线程退出时,内存是否保持分配状态?

Nic*_*ton 5 c++ multithreading pthreads

我在Linux上使用pthread库.

我在线程A中分配一个字符串,然后尝试在线程B中打印字符串.但是,字符串只打印出空(我已经验证它在线程A中有效).

注意:字符串驻留在一个对象内部,我怀疑它可能被清理或重新实例化为空...容器对象不会给我一个seg错误或任何东西,只是所有的值都是空的.

这是因为线程无法从其他线程访问内存,还是因为线程A停止后内存未被分配?或者它既不是; 它可能是我的代码中的一个错误,但我只想排除这个...

更新:

事实证明这是一个记忆问题.感谢您的回答,我也回答了这个问题,如果您同意/不同意,请对我的回答发表评论.

Max*_*xVT 9

与进程不同,线程在进程内共享一个公共内存空间(每个线程都有自己的堆栈,但堆通常是共享的).因此,当您退出线程时,不会自动释放从共享堆分配的内存.但是,例如,如果您已在堆栈上分配了一个字符串对象并通过一个简单的指针将其传递到某处,则析构函数将在线程退出时释放内存.


Nic*_*ton 0

事实证明,正如预期的那样,该问题是由内存使用不当引起的。我 99% 确信以下示例是准确的;它几乎是伪代码,因此显然无法编译。

更新:

感谢 nusi,刚刚添加了第三个解决方案。

错误的方式(使用堆栈内存):

std::map<int, MyType1> myMap;

void firstFunctionRunFromThread1()
{
    MyType1 mt1;
    mt1.Test = "Test 1";
    myMap[0] = mt1;
}

void onlyFunctionRunFromThread2()
{
    MyType1 mt1 = myMap[0];

    // This actually does print "Test 1", so the memory is being accessed.
    std::cout << mt1.Test << endl;

    /* However, because we're using stack memory here, this value is lost
     * when we go back to thread #1. */
    mt1.Test = "Test 2";
}

void secondFunctionFromThread1()
{
    MyType1 mt1 = myMap[0];

    // This will actually print out "Test 1", where "Test 2" is expected!
    std::cout << mt1.Test << endl;
}
Run Code Online (Sandbox Code Playgroud)

复杂正确的方法(使用堆内存):

另请参阅使用堆栈内存的简单方法。

std::map<int, MyType1> myMap;

void firstFunctionRunFromThread1()
{
    // Use heap memory so the memory stays allocated.
    MyType1 *mt1 = new MyType1();
    mt1->Test = "Test 1";
    myMap[0] = *mt1;
}

void onlyFunctionRunFromThread2()
{
    /* Now, get a pointer to the object; we can't use stack memory
     * here because the values assigned would be lost as soon as 
     * we try and access them from secondFunctionFromThread1() */
    MyType1 *mt1 = &myMap[0];

    // As expected, this prints "Test 1"
    std::cout << mt1->Test << endl;

    /* Now, because we're assigning to memory on the heap, this will
     * stay assigned until the entire application exits, yay! */
    mt1->Test = "Test 2";
}

void secondFunctionFromThread1()
{
    /* Not sure if using heap memory here is neccecary, but we'll do
     * it anwyay just to play on the safe side... let me know if this
     * is pointless... */
    MyType1 *mt1 = &myMap[0];

    // Hurray, this prints "Test 2"!!! :)
    std::cout << mt1->Test << endl;
}
Run Code Online (Sandbox Code Playgroud)

简单

感谢努西的回答

std::map<int, MyType1> myMap;

void firstFunctionRunFromThread1()
{
    MyType1 mt1;
    mt1.Test = "Test 1";
    myMap[0] = mt1;
}

void onlyFunctionRunFromThread2()
{
    /* Using the & before the variable turns it into a reference, so
     * instead of using stack memory, we use the original memory.
     * NOTE: Is this explanation correct? */
    MyType1 &mt1 = myMap[0];

    // This actually does print "Test 1", so the memory is being accessed.
    std::cout << mt1.Test << endl;

    // We're assigning to the reference, so this works.
    mt1.Test = "Test 2";
}

void secondFunctionFromThread1()
{
    MyType1 mt1 = myMap[0];

    // Prints "Test 1" as expected.
    std::cout << mt1.Test << endl;
}
Run Code Online (Sandbox Code Playgroud)