析构函数与内存释放

析构函数和内存释放,有一篇的总结,因为内容长,以后贴上来
先看个简易的
class A
{
public:
    A(int i = 3){a = i;};
    ~A(){cout << "destructor" << endl;}
    int value(){return a;}
private:
    int a;
};

int main()
{
    A a;
    A *p = new(&a) A(10);
    cout << a.value() << endl;
    delete p;
    return 0;
}

在a对象的地址上未析构a的时候,创建了新的无名堆对象,这样a的数据被覆盖了,
但是编译器并未收到析构函数调用的消息,所以它认为那块内存存放的仍然是a对象的数据,所以a.value()仍可以取回值,取回当时内存中那个地址处的值,这是已经是10了。
然后delete p的时候,执行两步工作,
1。无名对象的析构函数调用,告诉编译器,那块内存中的值不能解释成无名对象的数据了, 对于无名对象而言,已经无效了(但对于a对象而言,因为编译器并未收到a对象析构函数的调用,所以认为那块内存中的数据对于a而言仍是有效的,是a的数据的)
2。问题发生在这个时候,delete p的第二个动作,归还内存给系统,标识为 空闲内存(没有任何对象引用到的,没有任何函数占用的内存),而事实上,这是对于p所指对象而言,对于a对象,它仍引用到这块内存,这样产生了异常,系统认为是快空闲内存了,但确有个对象引用到了这块内存,行为属未定义。
      这就好像两个指针指向同一块的内存,一个把内存释放了,另一个指针成了悬垂指针,对悬垂指针解引用取出的值无意义,随机的,看当时内存中的数据

简单的说,
    构造函数就是通知编译器,这块内存的数据解释成一个对象,哪块是哪个数据成员的数据,这些信息是构造函数给编译器的,都是隐式给的;显式的动作 可以放在构造函数中(并未必需的)的,是初始化 (不给初始化值可以的,随机值),获取资源
    析构函数就是通知编译器,这块内存中的数据以后无需维护了,可以让其它使用了,里面的数据再不能解释成类对象的数据了,析构函数调用之后可以两种选择
    1。一般情况,归还内存,栈的,堆的,都是
    2。保留内存,只析构对象,这常见于placement new,delete往往同时执行了两个动作,所以这是候并不能直接delete,而是显式调用析构函数(详细论述待以后的总结)
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值