C++ delete[] void* 好奇心

Posted

技术标签:

【中文标题】C++ delete[] void* 好奇心【英文标题】:C++ delete[] void* curiosity 【发布时间】:2013-03-06 23:44:31 【问题描述】:

我有一个相当简单但很大的系统设置。它将数据存储在 void* 数组中,因为它存储的数据可能会在 floatdouble 之间变化,具体取决于所需的准确度。

只是使用 MinGW 进行 delete [] data 会引发 warning: deleting 'void*' is undefined [enabled by default]。我还有另一个变量告诉我datafloat* 还是double*,但我使用哪个重要吗?

换句话说,我可以使用闲置代码而不用担心内存泄漏或编译器未捕获的其他错误/损坏吗?

double* d_data = new double[length];
data = (void*)d_data;
delete [] (float*)data;

【问题讨论】:

你展示的代码调用了undefined behavior。 恕我直言 - 当您进行投射时,您通常会做错事。谨慎使用投射。 data = new unsigned char[lengthsizeof(double)];删除[](无符号字符)数据; @cppguy - 不要鼓励他! 大声笑,反正我在最后几行代码。除了满足对知识的渴望之外,所提供的答案不会改变任何东西。 【参考方案1】:

这确实很重要;您用于delete[] 的指针必须与您分配的指针具有相同的类型。所以转换为double* 是有效的(但容易出错);转换为 float* 会产生未定义的行为。

[对于类类型的单个对象(不是数组)有一个例外 - 它可以是指向基类的指针,如果该基类具有虚拟析构函数。但这不适用于像 double 这样的原始类型或数组。]

至于内存泄漏:手动内存管理总是存在内存泄漏的危险,除非您非常小心,绝不做任何可能引发异常的事情。我强烈推荐使用RAII 来管理所有动态资源。

【讨论】:

谢谢。我的好奇心得到了解答。【参考方案2】:

您似乎想使用union。

【讨论】:

我不想定义新的数据类型。我熟悉类、结构、Typedef、枚举和联合。我只是对删除分配的数据感到好奇。如果数据的“类型”是基本类型,例如 float、int、double、char 或任何其他基本数据类型,那么数据的“类型”是否真正重要。因为它们之间真正的变化是每个需要多少数据,以及你如何解释它。但是删除它呢? 在这种情况下是的,指针的数据类型决定了要删除的字节大小。浮点数采用 32 位,双倍 64 位。如果您将其释放为 float *,则它将删除元素 * 4 个字节,如果将其转换为 double *,则它将删除元素 * 8 个字节。【参考方案3】:

是的,这很重要(转换为其他数据类型本质上与离开 void* 一样糟糕),因为您实际上是在丢失/弄乱额外的元数据(如实际长度)。但它可能不一定会崩溃(例如,您也可以使用delete data; 而不是delete [] data;,除非编译器注意到错误,否则它会泄漏),因为它本质上是未定义的行为(不同的编译器或版本可能会产生不同的结果)。

正如 Jorge 建议的那样,您可能只想为此使用联合,这样两个数据类型可以共享相同的内存:

union my_union 
    double d_double;
    float d_float;
;

根据编译器的不同,这个结构通常与内部最大的数据类型大小相同(在这种情况下(在 32 位机器上)可能是 8 个字节的双精度,4 个字节的浮点数;所以总大小将是 8 个字节,因为这些变量本质上是重叠的)。请记住,您不能将其用于某种自动转换。

【讨论】:

以上是关于C++ delete[] void* 好奇心的主要内容,如果未能解决你的问题,请参考以下文章

Windows COM C++ - 使用删除或释放

public static void main(string[] args)解释

C++ 提升 asio 多线程

C++:delete void*问题

C# 中的哈希表比 C++ 更快?

C++ new int[0]——它会分配内存吗?