简体   繁体   English

C ++在堆分配的数据的二进制数组上删除-它会全部删除吗? 关于删除我应该知道些什么?

[英]C++ delete on binary array of heap allocated data - does it delete it all? What should I know about delete?

I just had this question pop in my head as I was reviewing some of my code I've used for quite a while to handle binary character arrays of data. 当我回顾一些我用来处理数据的二进制字符数组的代码时,我脑海中浮现出这个问题。

Does the following semi-pseudo C++ code accurately free myBinaryDataArray from the heap if it is filled with binary data (including the '\\0' character)? 如果myBinaryDataArray充满二进制数据(包括'\\ 0'字符),以下半伪C ++代码是否可以从堆中准确释放myBinaryDataArray? I'm sure there is documentation somewhere, I did a few searches though and didn't find a result - it was probably my wording. 我确定某个地方有文档,但是我进行了几次搜索,但没有找到结果-可能是我的措辞。

Code example: 代码示例:

char* myBinaryDataArray = new char[someLengthMyProgramNeeds];

/* mBinaryDataArray filled with binary data */

delete[] myBinaryDataArray;

I've been using the assumption that delete knows 'how' to delete correctly, but I recently had problems with delete on some objects after they were returned from a method (I noticed the destructor wasn't called). 我一直使用的假设是delete知道“如何”正确删除,但是最近我从某些方法返回某些对象后遇到了Delete问题(我注意到未调用析构函数)。 I'm now starting to question if I'm using it correctly. 我现在开始怀疑我是否正确使用了它。

Does anyone have a good resource or explanation on delete or how it works, and what I should keep in mind when using it? 是否有人对删除及其操作有很好的资源或说明,使用时应记住什么?

Also just to make sure it wasn't me.. If someone could let me know if calling delete on a returned heap allocated pointer of an object is not correct, why not? 同样,只是要确保它不是我。如果有人可以让我知道在返回的分配给对象的堆的指针上调用delete是不正确的,那为什么不呢? I've found something that compiles by deleting a cast of it to a pointer of the type it's supposed to be, but I don't know if that's correct. 我已经找到了一些可以通过将其类型转换删除为应该为该类型的指针而进行编译的东西,但是我不知道这是否正确。 I think I read something on it, but essentially I want to know more about delete in C++. 我想我读了一些东西,但是本质上我想了解有关C ++中删除的更多信息。

#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;
}

Output: 输出:

Destructor called

In response to: 回应:

Also just to make sure it wasn't me.. If someone could let me know if calling delete on a returned heap allocated pointer of an object is not correct, why not? 同样,只是要确保它不是我。如果有人可以让我知道在返回的分配给对象的堆的指针上调用delete是不正确的,那为什么不呢? I've found something that compiles by deleting a cast of it to a pointer of the type it's supposed to be, but I don't know if that's correct. 我已经找到了一些可以通过将其类型转换删除为应该为该类型的指针而进行编译的东西,但是我不知道这是否正确。 I think I read something on it, but essentially I want to know more about delete in C++. 我想我读了一些东西,但是本质上我想了解有关C ++中删除的更多信息。

It doesn't make a difference whether you returned the pointer from a function call, as long as the pointer is intact. 只要指针是完整的,是否从函数调用中返回指针都没有关系。 The only change in an object pointer should be done through the supported casts. 对象指针的唯一更改应通过支持的强制转换完成。

Even though new and delete are type-aware, they are still based on allocators and depend on the original pointer from new being passed back to delete . 即使newdelete具有类型感知能力,它们仍然基于分配器,并且依赖于new的原始指针,而new则被传递回delete Think of new and delete as the same counter in a book library or video rental store. 在图书库或视频租赁商店中,将“ new和“ delete视为同一计数器。

The correct thing to do is to only delete objects that you originally allocated with new or new[] , or let a smart pointer take care of deleting for you. 正确的做法是仅delete最初使用newnew[]分配的对象,或者让智能指针为您处理删除操作。

The new should usually go into a constructor, and the delete into a corresponding destructor, but can be in a factory method or anywhere else. new通常应放入构造函数中,而delete则应放入相应的析构函数中,但可以在工厂方法中或其他任何地方使用。

The reason for C++ virtual destructor is to allow correct deletion of a polymorphic type. 使用C ++虚拟析构函数的原因是允许正确删除多态类型。 As long as Base and Derived implement correct virtual destructors, all class managed resources will be freed correctly. 只要Base和Derived实现正确的虚拟析构函数,所有类管理的资源都将被正确释放。

The destructor will be executed based on the type information, but any code in the destructor will operate on the assumption that the original object lies at the pointer address. 析构函数将基于类型信息执行,但是析构函数中的任何代码都将在原始对象位于指针地址的假设下进行操作。 The allocator uses an algorithm like the buddy system that relies on where the pointer is, and bookkeeping information stashed at a relative offset of the object. 分配器使用像伙伴系统这样的算法,该算法依赖于指针的位置,并且簿记信息保存在对象的相对偏移处。 If you pass delete an altered pointer, it is a bug and will usually corrupt the heap. 如果您通过delete更改了指针,则它是一个bug,通常会破坏堆。

Does the following semi-pseudo C++ code accurately free myBinaryDataArray from the heap if it is filled with binary data (including the '\\0' character)? 如果myBinaryDataArray充满二进制数据(包括'\\ 0'字符),以下半伪C ++代码是否可以从堆中准确释放myBinaryDataArray?

No. If an exception or other control flow events (return comes to mind) occur before delete[] is called, it will leak. 否。如果在调用delete[]之前发生异常或其他控制流事件(回想起),它将泄漏。

I've been using the assumption that delete knows 'how' to delete correctly, but I recently had problems with delete on some objects after they were returned from a method (I noticed the destructor wasn't called). 我一直使用的假设是delete知道“如何”正确删除,但是最近我从某些方法返回某些对象后遇到了Delete问题(我注意到未调用析构函数)。 I'm now starting to question if I'm using it correctly. 我现在开始怀疑我是否正确使用了它。

If you're calling delete[] or delete yourself, the overwhelming likelihood is that you are not using it correctly. 如果您要调用delete[]delete自己,则绝大多数情况是您未正确使用它。 delete[] and delete are not useful for users. delete[]delete对用户没有用。

Does anyone have a good resource or explanation on delete or how it works, and what I should keep in mind when using it? 是否有人对删除及其操作有很好的资源或说明,使用时应记住什么?

There is nothing you need to keep in mind, since there is no need to use delete . 您无需记住任何内容,因为无需使用delete It is a useful primitive for library implementers. 对于库实现者来说,这是一个有用的原语。 Pretty much all the useful higher-level APIs on it are provided as Standard. 几乎所有有用的高级API都是标准提供的。

Even if you have some compelling use-case that absolutely cannot possibly be addressed by vector or unique_ptr / shared_ptr and friends in Boost, which is stupendously unlikely, there's still no motivation to use delete because any API worth using would take a deleter function and the Standard already provides one for delete . 即使您有一些引人注目的用例,但在Boost中绝对不可能由vectorunique_ptr / shared_ptr和朋友来解决(这是极不可能的),但仍没有使用delete动机,因为任何值得使用的API都会使用deleter函数,并且标准已经提供了一种delete

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM