是否可以删除子功能中的对象?

时间:2014-02-26 12:42:28

标签: c++ memory-leaks

我在C ++中遇到内存泄漏问题。

我创建了一个对象(新TYPE)并将其传递给子函数。 我知道我必须删除对象以避免内存泄漏 - 但是,当我在子函数中调用对象上的delete时,这会导致应用程序崩溃:

void subfunction (TYPE* oldObject,....) {
    //deep-copy object
    TYPE* object = new TYPE(oldObject->p1,oldObject->p2,....)
    subfunction (object,....)
    delete oldObject
}

这是什么问题?我是否必须删除与其创建的功能相同的对象?

我是否不允许删除函数中的对象,这是该函数的参数?

编辑:错误消息是 ' *`./a.out'出错:free():无效大小:0x00007fff4fbe59c0 * '

5 个答案:

答案 0 :(得分:2)

  

这里有什么问题?

你可能两次删除同一个对象。当你投掷指针并希望在适当的时候删除它时,这很容易做到。

  

我是否必须删除与其创建的功能相同的对象?

可以在任何地方删除它(只要你完成一次)。你不应该,因为玩杂耍的指针几乎不可能确保你完成一次。

  

我是否不允许删除函数中的对象,这是该函数的参数?

你被允许;但是你不应该这样做,因为调用者会留下一个悬空指针。如果它在删除对象后尝试对它做任何事情,那么就会出现各种错误。

除非你真的需要,否则请避免new;并使用智能指针管理您使用new创建的所有内容。然后你可以继续编写有用的代码,而不是调试一堆不稳定的内存损坏。

答案 1 :(得分:0)

问题是,在调用子函数(原始调用)之后,您可能正在引用其原始位置上的旧Object。

干杯。

答案 2 :(得分:0)

内存管理的问题在于,虽然它基本上相当简单(new / new [] - > delete / delete []),但当程序变得更复杂时,它变得棘手。

这就是为什么第一个建议是避免内存管理。这可以通过声明对象而不是指针并使用标准库容器来完成。

如果需要,使用RAII来处理内存管理(在析构函数中清理),最明显的是智能指针(std :: unique_ptr,std :: shared_ptr)。

使用(new / delete)进行内存管理时,在同一范围内分配和释放内存,以便更好地跟踪良好用途。

如果确实有必要,可以在其他范围内完成删除,例如功能,但它可能变得非常难以管理。

因此,在您的问题的代码中,没有任何内容直接指向崩溃,因此它必须与您未显示的代码结合使用。

答案 3 :(得分:0)

您显示的几行根本不允许诊断问题。正如其他答案和评论所说,这可能是由于删除了一个对象两次,或者可能是删除了new未首先给出的对象。或者可能是某些其他代码践踏您的指针,或者偏离分配的对象,delete最终看到的内容已损坏。

在C ++中,你可以做很多事情,而不是所有这些都是好主意。内存管理非常棘手。您可以将大部分内容留给语言(使用容器,智能指针等),或者您可以查找其中一个垃圾收集附加组件。

如果您想手动完成,请仔细定义以下几点:

  1. 谁负责或创建每种类型的对象?希望是一个简短的清单。
  2. 允许用户对该对象执行什么操作?更好地使它尽可能均匀。
  3. 谁负责处理这个物体?再次,希望是一个简短的清单。
  4. 确定每个对象都创建一次并在每个可能的路径上销毁一次代码(即匹配(1)和(3),确保(2)不干涉这个)
  5. 仔细考虑每个代码链,其中有多个指针指向同一个对象。他们中的哪一个“拥有”这个对象,如果需要的话,“欠款”是从一个人干净地交给下一个人的?这与上面的(1)和(3)相吻合吗?如果几个不同的指针传递给同一个对象,它会混淆一些(2)吗?
  6. 如果可能的话,在所有对象类型中设置一般规则(必须记住不同的规则,保证最终会应用错误的规则,并因此获得烟火)。一些简单的规则如上所述(例如,在同一范围内新建/删除;确保仅在构造函数中调用new,仅在析构函数中调用delete),但它们可能过于严格(堆上的对象和指针很精确,因为对象的生命周期不必与代码匹配。)

    考虑使用内存分配跟踪/调试工具,如valgrind。但依赖于他们,找到一个烂摊子并清理它比预先计划更多的工作。你可能没有注意到你的测试中的混乱,而墨菲的法则向你保证它会在最糟糕的时候崩溃或行为不端。

答案 4 :(得分:0)

我是开门人; 遗憾的是我的系统崩溃了,我没有存储trashmailaddress登录,因此我现在只能作为新用户回答

vonbrand实际上给出了正确的提示。第一个对象初始化为默认值

TYPE c; TYPE* cp =&c;

如何删除这样的元素?可能是自动地在它的范围的末尾,这导致了第二次删除操作,从而引起了我的问题。