我正在测试这段代码,看看程序内存是如何管理的,感谢windows资源监视器。
class A {
public:
string name_;
vector<double> H;
vector<float> G;
vector<string> I;
int abc;
};
list<A *> test (90000);
void allocate_class() {
for (list<A *>::iterator it= test.begin(); it != test.end();it++) {
A *ptr=*it;
ptr = new A;
}
}
void init_fct() {
for (list<A *>::iterator it= test.begin(); it != test.end();it++) {
A *ptr=*it;
/*
all above doesnt work program crash
(*ptr).name_ = "hello test";
ptr->name_ = "hello test";
ptr->abc = 57;
*/
}
}
void erase_class() {
list<A *>::iterator it= test.begin();
while( it != test.end() )
it = test.erase(it);
}
void delete_ptr() {
for (list<A *>::iterator it= test.begin(); it != test.end();it++) {
A *ptr=*it;
delete ptr;
}
}
int main()
{
int t;
cout << "before allocation" << endl;
cin >> t;
allocate_class();
cout << "after allocation" << endl;
cin >> t;
init_fct();
cout << "after init" << endl;
cin >> t;
erase_class();
cout << "after erase" << endl;
cout << test.size();
cin >> t;
delete_ptr();
cout << "after delete" << endl;
cout << test.size();
cin >> t;
问题:
在这种情况下是否真的需要operator delete部分?(不确定是否真的是空闲空间)
我在
init_fct()
中做错了什么?
注意:(属性是公共的,cin
是暂停程序并检查内存状态)
A *ptr=*it;
ptr = new A;
这使得复制(未初始化的)指针存储在你的列表中,然后分配给该副本(而不是列表上的指针)指向你新分配的A
实例的指针。然后副本超出作用域,就会出现内存泄漏。
当然,由于列表中的指针没有改变,以后使用它们会导致未定义的行为。
要解决这个问题,更改列表中的指针:
*it = new A;
关于你的erase_class
函数:它现在是正确的,在这个意义上,它清除了列表。但是,当您在删除列表中的指针之前调用它时,您仍然有内存泄漏:
首先从列表中删除所有指针,然后尝试删除分配的内存。但是由于你的列表中没有任何指针,迭代它将什么也不做。
看看你的目标,检查内存使用情况,它可能是你想要的东西:
list<A*> l;
cin >> dummy;
// The list will allocate space to hold the pointers:
l.resize (90000);
cin >> dummy;
// Allocate instances for each pointer in the list
for (auto & ptr : l) {
ptr = new A{};
}
cin >> dummy;
// Free the allocated instances
for (auto & ptr : l) {
delete ptr;
}
cin >> dummy;
// Erase all elements from the list.
// Note that this is not necessary, when
// the list goes out of scope at the end
// of main this is done by the list destructor.
// Moreover, there's a function to erase
// all elements from the list:
// l.clear();
auto it = l.begin();
while (it != l.end()) {
it = l.erase(it);
}
cin >> dummy;
请注意,使用智能指针(或者在本例中根本不使用指针)作为列表的元素,使您不必手动删除已分配的内存。