C++ delete[] void* curiosity

C++ delete[] void* curiosity

本文关键字:curiosity void delete C++      更新时间:2023-10-16

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

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

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

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

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

类类型的单个对象(不是数组)有一个例外——它可以是指向基类的指针,如果基类有虚析构函数,则。但这并不适用于基本类型,如double,或数组。] 对于内存泄漏:手动内存管理总是有内存泄漏的危险,除非您非常小心,永远不要做任何可能抛出异常的事情。我强烈建议使用RAII来管理所有的动态资源。

看起来您可能需要使用一个联合。

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

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

union my_union {
    double d_double;
    float d_float;
};

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