百分求解:这样会有内存泄露吗?

icerlion 2009-08-26 10:55:26
大致结构如下:
类CPacketData中封装了二进制数据,

class CPacketData
{
public:
CPacketData(void)
{
};
~CPacketData(void)
{
delete m_pData;
m_pData = NULL;
};
VOID SetData(BYTE* pData)
{
m_pData = pData;
}
private:
BYTE* m_pData;
};


在函数中,我会使用这个类,
但是二进制数据我是new出来的一个BYTE数组。

// Allocate buffer to store original data
BYTE* pData = new BYTE[100];
memset(pData, 0, 100);
// Allocate CPacketData class to manager the original data
CPacketData* pOriData = new CPacketData;
pOriData->SetData(pData);
// Do Something
// Free the memory
delete pOriData;
pOriData = NULL;


我的疑问是:
pData 我是new出来的一个数组,最后将其作为指针在CPacketData类中删除。
实测中发现没有内存泄露,
那我就奇怪了,
CPacketData类中管理的是一个BYTE指针,
而这个指针是new出来的一块内存,
如果我们仅仅删除指针,
应该仅仅删除了new出来的数组的第一个BYTE呀,
为什么后面的也连带释放了呢?


不是说new出来的数组需要用delete []pData;才能不会导致内存泄露吗?
...全文
189 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
liao05050075 2009-08-27
  • 打赏
  • 举报
回复
用new申请空间时,所用的空间会比你要的多出一点,多出来的那部分作为记录信息,以便你delete时使用。
所以,delete数组时,只要delete []array,而不用指定要删除多少。

但是,如果delete一个对象数组,只是使用delete array的话,那么这个数组只有首个对象被调用了析构函数。也就是说,如果你的对象所属的类中有new空间,然后在它的析构函数中delete的话,那么对象数组中除了首个对象外,剩余的对象所new出来的空间都泄漏了。
如果你delete的数组只是int,float之类的基本类型,那么调用delete []array,和delete array是没有区别的。
todaylxp 2009-08-27
  • 打赏
  • 举报
回复
class CPacketData
{
public:
CPacketData(void):
m_pData(NULL)
{
};

~CPacketData(void)
{
if(NULL != m_pData)
{
delete m_pData;
m_pData = NULL;
}
};
VOID SetData(BYTE* pData)
{
// 但如果传进来时栈地址,其实还会出问题,例如BYTE pData[1024];
if(NULL != m_pData)
{
delete m_pData;
m_pData = NULL;
}

m_pData = pData;
}
private:
BYTE* m_pData;
};
所以:
1.遵循谁申请谁释放
2.用智能指针
chenyu2202863 2009-08-27
  • 打赏
  • 举报
回复
请遵守“谁声请,谁释放”的原则
kakashi0309 2009-08-27
  • 打赏
  • 举报
回复
想说点什么的 发现6楼已经说了

对于new申请空间时,基本类型应该会记录申请空间的大小(好像是指针前面四个字节),供释放内存的时候调用
zjw6861982 2009-08-27
  • 打赏
  • 举报
回复
应该是行为未定义,不确定。
楼上的摆标准讲道理,很好
nineforever 2009-08-27
  • 打赏
  • 举报
回复
re,行为未定义

If it is not a null pointer value, in the first alternative (delete object), the value of the operand of delete shall be a pointer to a non-array object or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined.
In the second alternative (delete array), the value of the operand of delete shall be the pointer value which resulted from a previous array new-expression. If not, the behavior is undefined. [ Note: this means that the syntax of the delete-expression must match the type of the object allocated by new, not the syntax of the new-expression. —end note ]
野男孩 2009-08-27
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 icerlion 的回复:]
谢谢楼上两位,相关的帖子我已经看了。正在思考中。

不希望有人仅仅使用一句编译器优化来搪塞。
如果是编译器优化请指明编译器如何做的优化。

某位网友给出的标准比较不错。
[/Quote]

这不能称之为编译器优化,而是编译器的设计者想怎么做就怎么做了。C++标准要求非数组类型的对象用delete的形式,数组类型的对象用delete[]的形式。如果不是这样的话,那么行为是为定义的。

所以行为未定义就是指编译器可以任意处理,不同的编译器显然可能处理的方式不同,所以对于程序员来说结果就是未知的。可能完美的释放了,也可能程序会出错。

有些编译器对POD类型的数组处理比较宽松,delete或者delete[]来释放都算正确。但也仅是部分编译器吧。
再加上如果有重载new[],delete[]啥的,那就更容易出错了。

所以,尽量按C++标准来编写可移植性高的代码吧。
mstlq 2009-08-26
  • 打赏
  • 举报
回复
还是那句……
怕重写过的析构函数……
也怕重载过的operator delete
jackyjkchen 2009-08-26
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 icerlion 的回复:]
谢谢楼上两位,相关的帖子我已经看了。正在思考中。

不希望有人仅仅使用一句编译器优化来搪塞。
如果是编译器优化请指明编译器如何做的优化。

某位网友给出的标准比较不错。


[/Quote]

你可以联想一下C的内存分配,不管分配多少字节,一个free就行了,delete因为处理内置类型时调用的就是free或更底层的heapfree,因此对内置类型不需要[],不过好的编程风格应该加上
icerlion 2009-08-26
  • 打赏
  • 举报
回复
谢谢楼上两位,相关的帖子我已经看了。正在思考中。

不希望有人仅仅使用一句编译器优化来搪塞。
如果是编译器优化请指明编译器如何做的优化。

某位网友给出的标准比较不错。

mstlq 2009-08-26
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20090820/14/878a754d-cd83-4fc8-bd56-2fbc1c334c56.html?79333
不推荐这样写……
一般地来说,实际操作中出现这样的代码不大会引发问题,但是编译器不保证不出问题……
进一步,如果该类的operator delete被重载过的话,不正常的概率就直线上升了……
vincent_1011 2009-08-26
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20090820/14/878a754d-cd83-4fc8-bd56-2fbc1c334c56.html?79333
这里前几天讨论过

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧