2017-10-19 93 views
-2

結果我期望test1.cpp和test2.cpp發出類似的結果。
相同的打印每次運行,因爲沒有內存泄漏..
但它沒有。我不知道爲什麼。
請你讓我知道它是如何理解這種情況。weired從shared_ptr泄漏測試代碼

test1.cpp

#include <iostream> 
#include <memory> 
using namespace std; 

class Class { 
public: 
    shared_ptr<int> value1; 
    shared_ptr<int> value2; 
    Class() {}; 
}; 

int main() { 
    char pause; 
    while (true) { 
     shared_ptr<Class>cls(new Class()); 
     cout << cls.get() << endl; 
     cin >> pause; 
    } 
    return 0; 
} 

我的結果

0x94b5a10 
1 
0x94b5a28 
1 
0x94b5a10 
1 
0x94b5a28 
1 
0x94b5a10 

測試2.cpp

#include <iostream> 
#include <memory> 
using namespace std; 

class Class { 
public: 
    int value1; 
    int value2; 
    Class() {}; 
}; 

int main() { 
    char pause; 
    while (true) { 
     shared_ptr<Class>cls(new Class()); 
     cout << cls.get() << endl; 
     cin >> pause; 
    } 
    return 0; 
} 

我的結果

0x91baa10 
1 
0x91baa10 
1 
0x91baa10 
1 
0x91baa10 
1 
0x91baa10 

test3.cpp - 這是最weired結果..

#include <iostream> 
#include <memory> 
using namespace std; 

class Class { 
public: 
    shared_ptr<int> value1; 
    shared_ptr<int> value2; 
    shared_ptr<int> value3; 
    Class() {}; 
}; 

int main() { 
    char pause; 
    while (true) { 
     shared_ptr<Class>cls(new Class()); 
     cout << cls.get() << endl; 
     cin >> pause; 
    } 
    return 0; 
} 

我的結果

0x826ba10 
1 
0x826ba10 
1 
0x826ba10 
1 
0x826ba10 
1 
0x826ba10 
+3

無論是有效的行爲。你能解釋一下你的預期嗎?爲什麼你認爲另一個不好? – nvoigt

+0

https://ghostbin.com/paste/sft4q這是我的預期。對於鏈接抱歉。 stackoverflow系統很糟糕。 – combabo

+2

你可能/應該剛剛編輯你的問題,並把你的推理。 StackOverflow不是一個論壇。 – drescherjm

回答

0

在創建一個新的局部變量 shared_ptrcls每個迴路和對象的內存動態分配。當一個循環結束時,舊對象自動刪除,那麼新循環將創建一個新對象,因爲它是全新的,所以它不必與上一個循環中的舊對象具有相同的地址。兩個結果都是正常的,兩種情況都可能發生。

2

您打印的是類(錯誤名稱)對象的地址。

在第二種情況下,您的Class對象在shared_ptr超出範圍並且在同一內存位置分配了新對象時被釋放。這是好的。

在第一種情況下,出於某種原因,爲新的Class對象選擇了不同的地址。從經驗上講,它必須與所做的其他分配和釋放有關。沒有看分配器的內部邏輯,你不會得到比這更準確的答案。

而且,在任何情況下,您絕對不應該依賴任何類型的邏輯之後的地址。你應該根本不在乎。

0

問題解決了。我期望的是每個本地對象將在while循環結束時被刪除(在這種情況下,test4.cpp在測試函數結束時)。但它沒有。

test4.cpp

#include <iostream> 
#include <memory> 
using namespace std; 

class Class { 
public: 
    shared_ptr<int> value1; 
    shared_ptr<int> value2; 
    Class() {}; 
}; 

char test() { 
    char pause; 
    shared_ptr<Class>cls(new Class()); 
    cout << cls.get() << endl; 
    cin >> pause; 
    return pause; 
} 

int main() { 
    while (true) { 
     if ('q' == test()) break; 
    } 
    return 0; 
} 

測試結果

[email protected]:~# ltrace -C ./test 
__libc_start_main(0x8048d2f, 1, 0xffffd4c4, 0x8048fc0 <unfinished ...> 
std::ios_base::Init::Init()(0x804b1d9, 0x4a00, 0xf7c81dc8, 0xf7ffb000) = 0xf7fbde14 
__cxa_atexit(0x8048920, 0x804b1d9, 0x804b05c, 0xf7ffb000) = 0 
operator new(unsigned int)(16, 0xffffd4c4, 0xf7fb608c, 0x8048d69) = 0x8050a10 
operator new(unsigned int)(16, 0xffffd4c4, 0xf7fb608c, 0x8048d69) = 0x8050a28 
std::ostream& std::ostream::_M_insert<void const*>(void const*)(0x804b120, 0x8050a10, 0xf7fb608c, 0x8048d69) = 0x804b120 
std::ostream::put(char)(0x804b120, 10, 0xf7fb608c, 0x8048d690x8050a10 
) = 0x804b120 
std::ostream::flush()(0x804b120, 10, 0xf7fb608c, 0x8048d69) = 0x804b120 
std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char> >(std::basic_istream<char, std::char_traits<char> >&, char&)(0x804b060, 0xffffd3f3, 0xf7fb608c, 0x8048d691 
) = 0x804b060 
operator delete(void*, unsigned int)(0x8050a10, 16, 0xf7f26f0b, 0xf7fbd660) = 0 
operator delete(void*, unsigned int)(0x8050a28, 16, 0xf7f26f0b, 0xf7fbd660) = 0x8050a08 
operator new(unsigned int)(16, 0xffffd3f3, 0xf7fb608c, 0x8048d69) = 0x8050a28 
operator new(unsigned int)(16, 0xffffd3f3, 0xf7fb608c, 0x8048d69) = 0x8050a10 
std::ostream& std::ostream::_M_insert<void const*>(void const*)(0x804b120, 0x8050a28, 0xf7fb608c, 0x8048d69) = 0x804b120 
std::ostream::put(char)(0x804b120, 10, 0xf7fb608c, 0x8048d690x8050a28 
) = 0x804b120 
std::ostream::flush()(0x804b120, 10, 0xf7fb608c, 0x8048d69) = 0x804b120 
std::basic_istream<char, std::char_traits<char> >& std::operator>><char, std::char_traits<char> >(std::basic_istream<char, std::char_traits<char> >&, char&)(0x804b060, 0xffffd3f3, 0xf7fb608c, 0x8048d69q 
) = 0x804b060 
operator delete(void*, unsigned int)(0x8050a28, 16, 0xf7f26f0b, 0xf7fbd660) = 0 
operator delete(void*, unsigned int)(0x8050a10, 16, 0xf7f26f0b, 0xf7fbd660) = 0x8050a20 
std::ios_base::Init::~Init()(0x804b1d9, 0, 0, 0xf7ca38d7) = 0xf7fbc5c0 
+++ exited (status 0) +++