这个C++代码是否会导致内存泄漏(将数组转换为新的)

Rob*_*Rob 10 c++ memory-leaks memory-management

我一直在研究一些使用可变长度结构(TAPI)的遗留C++代码,其中结构大小将取决于可变长度字符串.结构由铸造数组分配,new因此:

STRUCT* pStruct = (STRUCT*)new BYTE [sizeof(STRUCT) + nPaddingSize];

然后,稍后使用delete调用释放内存:

delete pStruct;
Run Code Online (Sandbox Code Playgroud)

这种数组new []和非数组的混合delete会导致内存泄漏还是依赖于编译器?我是否会更好地更改此代码以使用mallocfree不是?

Rob*_*ker 12

从技术上讲,我认为它可能会导致分配器不匹配的问题,但在实践中我不知道任何编译器不能用这个例子做正确的事情.

更重要的是,如果STRUCT在哪里(或曾经给过)析构函数,那么它将在不调用相应的构造函数的情况下调用析构函数.

当然,如果您知道pStruct来自何处,为什么不将其强制转换为删除以匹配分配:

delete [] (BYTE*) pStruct;
Run Code Online (Sandbox Code Playgroud)


Mat*_*ank 7

我个人认为你最好不要std::vector用来管理你的记忆,所以你不需要delete.

std::vector<BYTE> backing(sizeof(STRUCT) + nPaddingSize);
STRUCT* pStruct = (STRUCT*)(&backing[0]);
Run Code Online (Sandbox Code Playgroud)

一旦支持离开范围,您pStruct就不再有效.

或者,您可以使用:

boost::scoped_array<BYTE> backing(new BYTE[sizeof(STRUCT) + nPaddingSize]);
STRUCT* pStruct = (STRUCT*)backing.get();
Run Code Online (Sandbox Code Playgroud)

或者,boost::shared_array如果您需要移动所有权.


sli*_*ime 6

代码的行为是未定义的.你可能很幸运(或者没有)它可能与你的编译器一起使用,但实际上这不是正确的代码.有两个问题:

  1. delete应该是一个数组delete [].
  2. delete应在指向同一类型分配的类型来调用.

所以说完全正确,你想要做这样的事情:

delete [] (BYTE*)(pStruct);
Run Code Online (Sandbox Code Playgroud)


Len*_*ate 6

是的,它会导致内存泄漏.

除了C++ Gotchas之外,请看这个: http://www.informit.com/articles/article.aspx?p=30642为什么.

Raymond Chen解释了如何使用矢量newdelete不同于Microsoft编译器封面下的标量版本......这里: http://blogs.msdn.com/oldnewthing/archive/2004/02/03/66660.aspx

恕我直言你应该修复删除:

delete [] pStruct;
Run Code Online (Sandbox Code Playgroud)

而不是切换到malloc/ free,只是因为它是一个更简单的改变,而不会犯错误;)

而且,当然,由于原始分配中的转换,我在上面显示的更简单的更改是错误的,它应该是

delete [] reinterpret_cast<BYTE *>(pStruct);
Run Code Online (Sandbox Code Playgroud)

所以,我想这可能很容易切换到malloc/ free毕竟;)