当C ++线程退出时,内存是否保持分配状态? [英] Does memory stay allocated when a C++ thread exits?

查看:106
本文介绍了当C ++线程退出时,内存是否保持分配状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Linux上使用pthread库.

我在线程A中分配了一个字符串,然后尝试在线程B中打印该字符串.但是,该字符串只是打印为空(我已经验证了它在线程A中可以使用).

注意:该字符串位于一个对象内部,我怀疑它可能正在被清理或重新实例化为空...容器对象没有给我seg错误或其他任何东西,只是所有值都是空的. /p>

是因为线程无法从其他线程访问内存,还是因为线程A停止后正在分配内存?还是两者都不是;可能是我代码中的错误,但我只是想排除这一点...

更新:

原来是内存问题.感谢您的回答,我也回答了我的问题自我,如果您同意/不同意,请对我的回答发表评论.

解决方案

事实证明,该问题是由于内存使用不正确所引起的.我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;
}

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

另请参阅使用堆栈存储器的简单方法.

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;
}

简单,正确的方法(正确使用堆栈内存):

感谢nusi提供他的答案.

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;
}

I'm using the pthread library on Linux.

I'm assigning a string in thread A, and then trying to print the string in thread B. However, the string just prints out empty (I have verified that it works in thread A).

Note: The string resides inside an object, which I suspect may be getting cleaned up or re-instantiated empty... The container object doesn't give me a seg fault or anything, just all the values are empty.

Is this because threads cannot access memory from other threads, or because the memory is being unallocated once thread A stops? Or is it neither; it could well be a bug in my code, but I just wanted to rule this out...

Update:

Turns out it was a memory issue. With thanks to your answers, I have also answered this my self, please do comment on my answer if you agree/disagree.

解决方案

Turns out, the issue was caused by incorrect use of memory, as expected. I'm 99% sure the following example is accurate; it's pretty much pseudo code, so wont compile, obviously.

Update:

Just added a 3rd solution thanks to nusi.

The wrong way (with stack memory):

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;
}

The complicated, correct method (using heap memory):

See also the simple method which uses stack memory.

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;
}

The simple, correct method (using stack memory correctly):

Thanks to nusi for his answer.

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;
}

这篇关于当C ++线程退出时,内存是否保持分配状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆