我一直在研究一些使用可变长度结构(TAPI)的遗留C++代码,其中结构大小将取决于可变长度字符串.结构由铸造数组分配,new
因此:
STRUCT* pStruct = (STRUCT*)new BYTE [sizeof(STRUCT) + nPaddingSize];
然后,稍后使用delete
调用释放内存:
delete pStruct;
这种数组new []
和非数组的混合delete
会导致内存泄漏还是依赖于编译器?我是否会更好地更改此代码以使用malloc
而free
不是?
从技术上讲,我认为它可能会导致分配器不匹配的问题,但在实践中我不知道任何编译器不能用这个例子做正确的事情.
更重要的是,如果STRUCT
在哪里(或曾经给过)析构函数,那么它将在不调用相应的构造函数的情况下调用析构函数.
当然,如果您知道pStruct来自何处,为什么不将其强制转换为删除以匹配分配:
delete [] (BYTE*) pStruct;
我个人认为你最好不要std::vector
用来管理你的记忆,所以你不需要delete
.
std::vectorbacking(sizeof(STRUCT) + nPaddingSize); STRUCT* pStruct = (STRUCT*)(&backing[0]);
一旦支持离开范围,您pStruct
就不再有效.
或者,您可以使用:
boost::scoped_arraybacking(new BYTE[sizeof(STRUCT) + nPaddingSize]); STRUCT* pStruct = (STRUCT*)backing.get();
或者,boost::shared_array
如果您需要移动所有权.
代码的行为是未定义的.你可能很幸运(或者没有)它可能与你的编译器一起使用,但实际上这不是正确的代码.有两个问题:
的delete
应该是一个数组delete []
.
本delete
应在指向同一类型分配的类型来调用.
所以说完全正确,你想要做这样的事情:
delete [] (BYTE*)(pStruct);
是的,它会导致内存泄漏.
除了C++ Gotchas之外,请看这个: http://www.informit.com/articles/article.aspx?p=30642为什么.
Raymond Chen解释了如何使用矢量new
和delete
不同于Microsoft编译器封面下的标量版本......这里:
http://blogs.msdn.com/oldnewthing/archive/2004/02/03/66660.aspx
恕我直言你应该修复删除:
delete [] pStruct;
而不是切换到malloc
/ free
,只是因为它是一个更简单的改变,而不会犯错误;)
而且,当然,由于原始分配中的转换,我在上面显示的更简单的更改是错误的,它应该是
delete [] reinterpret_cast(pStruct);
所以,我想这可能很容易切换到malloc
/ free
毕竟;)