我有以下代码段
class test{
private:
int *ptr;
public:
test(int *myptr){
ptr = myptr;
}
~test(){
delete ptr;
}
};
int main(){
int* myptr = new int;
*myptr = 10;
test obj(myptr);
delete myptr;
}
在这个程序中是否发生内存泄漏,如果我不在表中对指针进行新操作,是否会为该指针分配空间?
答案 0 :(得分:1)
处理分配成员的经验法则:每个new
/ new[]
应与一个delete
/ delete[]
配对。如果你错过了delete
,那么你就有内存泄漏(你已经分配了永远不会清理的内存)。如果您是delete
- 倍数,就像您在此代码示例中所做的那样,您将遇到内存损坏问题。
你如何delete
多次?在main()
中,您分配一个指针:
int* myptr = new int;
您将指针的副本提供给test
对象obj
。然后,在范围的最后我们有:
{
// ...
delete myptr;
~test(); // implicit, which also does delete myptr
}
这两个地方中只有一个应负责delete
指针。哪一个基于代码的语义。 test
拥有指针吗?在这种情况下,它应delete
,但main()
不应该。delete
。它只是观察指针吗?在这种情况下,它不应该def build_module_clean(globals, module_string, attr_strings):
module = import_module(module_string)
module = reload(module)
globals[module_string] = module
for f in attr_strings:
globals[f] = getattr(module, f)
它。使用C ++ 11,我们有了新的智能指针来更好地表达这个想法。
我建议您浏览definitive C++ book list,因为这样的概念对理解C ++非常重要,但很难用简短的Q& A格式正确解释。
答案 1 :(得分:0)
您应该只在~test()
或delete
直接删除指针
*** Error in `./a.out': double free or corruption (fasttop): 0x08d13a10 ***
答案 2 :(得分:0)
考虑使用std::shared_ptr<int>
或std::unique_ptr<int>
,因为在现代C ++中不鼓励使用直接内存管理,除非您有理由这样做。
您可以阅读智能指针here的语义差异,它们的引用是here。
答案 3 :(得分:0)
在您的实例中将会发生的事情是指针将被赋予delete
中的main()
,然后在析构函数中第二次将相同的指针值赋予delete
obj
。这是未定义的行为,因此它可能有用,或者它可能不会,在任何情况下,它都不能保证工作,因此不应使用这样的构造。
通常你会建立所有权规则,例如构造函数“取得所有权”(因此负责释放资源)取决于您,但通常情况下,尤其是在现代C ++中,使用std::unique_ptr
和std::shared_ptr
可以清楚地实现所有权语义。
最重要的是,无论您使用哪种方法来确定所有权,都要确保一致!避免复杂的所有权语义,因为它会使检测与内存相关的问题(或者更常见的是与资源相关的问题)变得更加困难。
答案 4 :(得分:0)
退出主函数时会崩溃,堆内存中分配的内容不能释放两次
答案 5 :(得分:0)
与其他人说的相反:你不会删除C ++中的指针,而是对象。
有什么区别?
让我们简化一下你的代码:
int *myptr = new int; // 1
int *ptr = myptr; // 2
delete myptr; // 3
delete ptr; // 4
就new
和delete
的使用而言,这是相同的代码 - 我刚刚删除了该类,因为它与此处的要点无关。
此代码执行以下操作:
new int
分配int
,并返回其地址。然后将地址存储在myptr
。ptr
。 ptr
和myptr
都包含刚刚分配的int
的地址。int
已取消分配。 int
已取消分配...但它已被解除分配?糟糕!
如果你很幸运,你的程序将在此时崩溃。
delete myptr;
与变量myptr
无关,只是myptr
包含要删除的内容的地址。
它甚至不必是变量 - 您可以delete new int;
(尽管它不是非常有用)或delete someFunctionThatReturnsAnAddress();
或int *p = 1 + new int[2]; delete [] (p - 1);
。
答案 6 :(得分:-1)
您的类只有已分配整数的引用。考虑将其声明为int const* ptr
,然后您无法在类中删除它。
您应该从析构函数中删除delete ptr
。
通常,分配内容的范围负责释放它。在你的情况下,主程序是分配,必须释放。
答案 7 :(得分:-1)
对于你的问题&#34;在这个程序中是否发生内存泄漏&#34;,答案是否定的,但是一个例外是正在发生。
您的代码逻辑不好,您应该删除创建它的位置的指针。在这个例子中,你不应该在析构函数中删除ptr。