我期望test1.cpp和test2.cpp发出类似的结果。
每次运行都打印相同,因为没有内存泄漏。
但事实并非如此。我不知道为什么。
请您告诉我了解这种情况是什么。
测试1.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 - 这是最奇怪的结果。
#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
您打印的是类(错误名称)对象的地址。
在第二种情况下,当shared_ptr超出范围并在相同的内存位置分配一个新对象时,您的 Class 对象将被释放。这没关系。
在第一种情况下,出于某种原因,为新的 Class 对象选取了不同的地址。从经验上讲,它必须与所做的其他分配和交易有关。如果不查看分配器的内在逻辑,您将不会得到比这更精确的答案。
而且,在任何情况下,您绝对不应该依赖遵循任何类型的逻辑的地址。你根本不应该在乎。
在每个循环中创建一个新的局部变量shared_ptrcls,并动态分配对象的内存。当一个循环结束时,旧对象会自动删除,然后新循环将创建一个新对象,并且它不必与最后一个循环中的旧对象具有相同的地址,因为它是全新的。这两种结果都是正常的,两种情况都可能发生。
问题解决了。 我期望的是每个本地对象都将在 while 循环结束时删除(在本例中为 test4.cpp在测试函数结束时)。 但它没有。
测试4.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;
}
测试结果
root@real:~# 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) +++