C ++动态分配不匹配:这有问题吗?

时间:2010-06-07 18:53:38

标签: c++ memory-leaks memory-management

我被指派在MFC中处理一些遗留的C ++代码。我在这个地方找到的一件事是分配如下:

struct Point
{
   float x,y,z;
};

...

void someFunc( void )
{
   int numPoints = ...;
   Point* pArray = (Point*)new BYTE[ numPoints * sizeof(Point) ];
   ...
   //do some stuff with points
   ...
   delete [] pArray;
}

我意识到这个代码在很多层面都是错误的(C风格的演员,使用像new这样的malloc,令人困惑等等。我也意识到,如果 Point 定义了一个构造函数,那么如果定义了析构函数,它就不会被调用,而delete []会发生奇怪的事情。

问题: 我正在修理这些事件,无论它们出现在哪里都是理所当然的。然而,我以前从未见过这样的事情,它有让我疑惑此代码是否有可能导致内存泄漏/损坏,因为它当前(没有构造函数/析构函数,但指针类型不匹配),或者只要数组只包含结构/基元类型,它是否安全?

4 个答案:

答案 0 :(得分:6)

由于new[] / delete[]中的指针类型不匹配,因此代码正式导致未定义的行为。在实践中它应该工作正常。

通过向delete-expression

添加强制转换,可以轻松修复指针类型不匹配问题
delete [] (BYTE *) pArray;

如果Point类型定义为问题中所示(即使用简单的构造函数和析构函数),则此更正解决了此代码中存在的所有正式问题。从语言的角度来看,具有普通构造函数(析构函数)的对象的生命周期与其存储持续时间同时开始(结束)。即没有要求执行构造函数(析构函数)的实际调用。

答案 1 :(得分:1)

只要构造函数和析构函数不执行任何操作,那么您就是安全的。

答案 2 :(得分:0)

只要您确保它确实为每个delete[]调用匹配的new[],它就不会泄漏 - 但是如果任何被评论的代码都可能抛出异常out,这将很难保证(基本上,你需要捕获任何可能的异常,删除内存,然后重新抛出异常)。

答案 3 :(得分:0)

我首先要弄清楚为什么代码首先以这种方式编写。这可能只是因为程序员不知道更好,或者因为他们试图在编译器中解决一些时髦的缺陷。但可能有一个你不知道的真正原因。如果有,那么除非您理解该原因及其副作用,否则您可能会通过更改此代码来引入缺陷。

这样做,并且假设代码现在没有特殊原因需要这样,你应该安全地更改代码以使用更现代和正确的结构。

但为什么呢?我理解使代码更正确的动机。但是你真正获得了什么呢?如果代码以现在的方式运行(一个很大的假设),那么通过更改代码,您可能会获得使代码更易于理解的好处,但是您更改的每一行代码都会引发新错误的可能性。写的。

如果最后你决定继续改变,为什么要中途停止?考虑完全删除所有newdelete,并将其替换为vector等。