我有以下代码:
void someFunction() {
.......
myClass obj= *(new myClass());
........
delete &obj;
}
我收到运行时错误,指出无效指针。
代码运行正常,没有“删除”行。
我知道我需要重新声明新运营商动态分配的内存。但我不知道在这种情况下发生了什么,我怎么甚至需要释放内存?
由于
答案 0 :(得分:4)
如果您的意图是实例只存在于此函数的范围内,那么您不需要使用动态分配......
void someFunction() {
.......
myClass obj;
........
}
...在这种情况下,obj
构造函数在myClass obj
处声明时被调用,并且在函数返回时调用析构函数。否则,如果它必须是动态的,那么......
void someFunction() {
.......
myClass* obj = new myClass();
........
delete obj;
}
...在这种情况下,当您调用new myClass()
时调用构造函数,并在调用delete obj
时调用析构函数 - 但是,在这种情况下,您需要声明{{1} }是一个指向obj
对象的指针,以便有一个存储来自myClass
的返回值的地方。
答案 1 :(得分:2)
在你的例子中,我认为你不能重新获得记忆。
obj是您使用*(new myClass())创建的匿名类的副本。 “obj”在堆栈上分配...它没有在堆上分配(这是新分配的地方)。
当您尝试删除& obj时,您试图删除您创建的副本的堆栈内存。
尝试类似
的内容myClass *obj = new myClass(); // memory is allocated from the heap and a pointer returned
myClass copyOfObj = *obj; // memory is allocated on the stack. a *shallow* copy of obj is made
delete obj.
答案 2 :(得分:1)
你的obj
变量必须保存对解除引用指针的引用,以便以后可以(相当奇怪地)删除它:
myClass& obj;
// ^
但是你不需要这样定义它,你可以定义一个指向内存的指针:
myClass* obj = new myClass();
并以这种方式删除它:
delete obj;
或者,更好的是,您可以使用std::unique_ptr
等内存管理工具:
std::unique_ptr<myClass> obj(new myClass);
但据我所知,动态内存确实没用,只是将它作为普通变量实例化:
myClass obj;
答案 3 :(得分:1)
myClass obj= *(new myClass());
首先创建一个myClass
对象,其自动存储持续时间名为obj
。该对象由表达式*(new myClass())
初始化。此表达式动态分配myClass
对象,然后取消引用指向该对象的指针。所以你最终在这里做的是动态分配一个对象,然后将复制到obj
。
您现在已经忘记了动态分配的对象。这不好。执行delete &obj;
只会获取自动对象的地址并尝试销毁它,但您只能将delete
与动态分配的对象一起使用。
你可以更改obj
作为参考,它会起作用:
myClass& obj = *(new myClass());
这确保不会复制动态分配的对象。但是,这不是一个好主意。它掩盖了obj
引用必须为delete
d的对象这一事实。相反,你最好存储指针本身:
myClass* obj = new myClass();
// ...
delete obj;
甚至更好,使用像std::unique_ptr<myClass>
这样的智能指针。
甚至更好,甚至都不动态分配它。只需使用自动对象:
myClass obj;
// No need to allocate or delete anything
答案 4 :(得分:1)
myClass obj= *(new myClass());
那一行:
myClass
实例。myClass
。obj
。丢弃指向动态分配对象的指针,导致内存泄漏。delete
,这会导致未定义的行为。此对象未分配new
或new
的任何变体。您的代码应为:
myClass *p = new myClass();
// use p
delete p;
您可能根本不需要动态内存分配,所以......
myClass obj; // that's it!
接下来,阅读智能指针。
std::unique_ptr<myClass> p(new myClass());
// no delete! unique_ptr handles it for you when it goes
// out of scope and has the benefit of being exception safe.