我期望test1.cpp和test2.cpp发出类似的结果
每次运行都打印相同,因为没有内存泄漏。
但事实并非如此。我不知道为什么。
你能不能让我知道它是如何理解这种情况的。
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 - 这是最令人满意的结果..
#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
答案 0 :(得分:2)
您要打印的是Class(错误名称)对象的地址。
在第二种情况下,当shared_ptr超出范围并且在同一内存位置分配新对象时,将释放Class对象。哪个好。
在第一种情况下,由于某种原因,为新的Class对象选择了不同的地址。根据经验,它必须与所做的其他分配和解除分配有关。如果不看分配器的内部逻辑,你就不会得到比这更精确的答案。
而且,无论如何,你绝对不应该依赖任何类型逻辑之后的地址。你应该根本不在乎。
答案 1 :(得分:0)
在每个循环中,创建一个新的局部变量 shared_ptrcls,并为该对象的内存分配动态。当一个循环结束时,旧对象自动删除,然后新循环将创建一个新对象,并且它不必具有与上一循环中旧对象相同的地址,因为它是全新的。两种结果都是正常的,两种情况都可能发生。
答案 2 :(得分: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;
}
测试结果
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) +++