C ++删除堆分配数据的二进制数组 - 是否将其全部删除?关于删除我应该知道些什么?

时间:2014-10-26 21:40:30

标签: c++

我正在审视我的一些代码,我已经用了很长一段时间来处理二进制字符数据数组。

如果填充了二进制数据(包括' \ 0'字符),以下半伪C ++代码是否可以准确地从堆中释放myBinaryDataArray?我确定某处有文档,我做了一些搜索,但没有找到结果 - 这可能是我的措辞。

代码示例:

char* myBinaryDataArray = new char[someLengthMyProgramNeeds];

/* mBinaryDataArray filled with binary data */

delete[] myBinaryDataArray;

我一直在使用删除知道'如何'要正确删除,但我最近在一些对象从方法返回后删除了一些问题(我注意到析构函数没有被调用)。我现在开始质疑我是否正确使用它。

是否有人有关于删除或其工作方式的良好资源或解释,以及使用它时应该记住的内容?

也只是为了确保它不是我..如果有人可以让我知道如果在返回的堆上调用delete分配的对象指针不正确,为什么不呢?我已经找到了一些可以通过删除它的指针来编译的东西,但是我不知道它是否正确。我想我已经阅读了一些内容,但基本上我想知道更多关于C ++中的删除。

3 个答案:

答案 0 :(得分:0)

#include <iostream>

class foo {
public:
  ~foo() { std::cout << "Destructor called" << std::endl; }
};

class bar {
public:
  foo* myMethod() { return new foo(); }
};

int main(int argc, char** argv)
{
  bar b;
  foo* f = b.myMethod();

  delete f;
}

输出:

Destructor called

回应:

  

也只是为了确保它不是我..如果有人可以让我知道如果在返回的堆上调用delete分配的对象指针不正确,为什么不呢?我已经找到了一些可以通过删除它的一个类型的指针来编译的东西,但我不知道这是否正确。我想我已经阅读了一些内容,但基本上我想知道更多关于C ++中的删除。

答案 1 :(得分:0)

只要指针完好无损,是否从函数调用返回指针并没有什么区别。对象指针的唯一变化应该通过支持的强制转换完成。

即使newdelete是类型感知的,它们仍然基于分配器,并依赖于new传递回delete的原始指针。将newdelete视为图书馆或视频租赁商店中的同一个计数器。

正确的做法是只使用最初使用deletenew分配的new[]个对象,或者让智能指针为您进行删除。

new通常应该进入构造函数,delete应该进入相应的析构函数,但可以使用工厂方法或其他任何地方。

C ++虚拟析构函数的原因是允许正确删除多态类型。只要Base和Derived实现了正确的虚拟析构函数,所有类管理的资源都将被正确释放。

析构函数将根据类型信息执行,但析构函数中的任何代码都将在假设原始对象位于指针地址的情况下运行。分配器使用类似于伙伴系统的算法,该算法依赖于指针所在的位置,并且簿记信息存储在对象的相对偏移处。如果你传递delete一个改变的指针,它就是一个bug,通常会破坏堆。

答案 2 :(得分:-3)

  

以下半伪C ++代码是否准确无误   如果填充了二进制数据,则来自堆的myBinaryDataArray   (包括'\ 0'字符)?

没有。如果在调用delete[]之前发生异常或其他控制流事件(返回想到),它将泄漏。

  

我一直在使用删除知道'如何'删除的假设   正确,但我最近有一些对象删除问题   他们从一个方法返回后(我注意到了析构函数   没被叫)。我现在开始质疑我是否正在使用它   正确。

如果您自己致电delete[]delete,则压倒性的可能性是您没有正确使用它。 delete[]delete对用户无用。

  

是否有人有关于删除或如何删除的良好资源或解释   工作,以及使用它时我应该记住什么?

您无需记住任何内容,因为无需使用delete。它对于库实现者来说是一个有用的原语。几乎所有有用的高级API都以标准形式提供。

即使你有一些令人信服的用例,vectorunique_ptr / shared_ptr以及Boost中的朋友绝对无法解决这种情况,这种情况几乎不可能,但仍然没有动力使用delete因为任何值得使用的API都会使用删除功能,标准已经为delete提供了一个。