zoukankan      html  css  js  c++  java
  • 不要轻易delete void*指针,这样会隐藏比较多的错误。

     1 #include<iostream>
     2 using namespace std;
     3 
     4 class Object{
     5     void* data;
     6     const int size;
     7     const char id;
     8 public:
     9     Object(int sz, char c) :size(sz),id(c){
    10         data = new char[size];
    11         cout << "Constructor Object" << id << ",size=" << size << endl;
    12     }
    13     ~Object(){
    14         cout << "Destructing object" << id << endl;
    15         delete[]data;
    16     }
    17     
    18 };
    19 
    20 int main(){
    21     Object* a = new Object(40,'a');
    22     delete a;
    23     void* b = new Object(41,'b');//会调用构造函数
    24     delete b;//不会调用析构函数
    25 
    26          return 0;

    }

    首先我们来开一下这个类的内存模型。

    在运行结果截图中,我们看到

    Object* a = new Object(40,'a');
    delete a;
    可以正确的构造对象,在析构函数中也可以把用delete把data指针指向的内存释放掉。(在对void*类型的内存使用delete,并不会发生错误,仅仅是把内存释放掉。)但是在main函数中,我们看到delete知道它所操作的对象的类型是十分重要的。我们看到
    void* b = new Object(41,'b');//会调用构造函数
       delete b;//不会调用析构函数
    在用delete删除b的操作中,我们只是对b指向的对象进行了释放,并没有调用构造函数,也就是说data指向的内存并没有被释放,而此时又没有指针指向刚才data指针指向的内存,从而造成了内存的丢失,更会造成内存的泄露。


    这会有一个比较有意思的地方就是如果写下面的代码,
    Object* pc=(Object*)malloc(sizeof(Object));//这个事情我们在new delete运算符与malloc free库函数的区别中讲到过,这时候不会调用构造函数,只会分配内存
    delete pc;//而这句话因为pc是有类型的,不是void*所以会调用析构函数
  • 相关阅读:
    Kubernetes组件及网络基础
    mybatis小结-001
    mysql+navicat安装小结
    ibatsi学习总结
    linux 相关的问题
    java 基础 --int 和Integer的区别
    java 接口和抽象类的区别
    java 堆和栈的区别
    springMVC controller配置方式总结
    GC是什么?为什么要有GC
  • 原文地址:https://www.cnblogs.com/cplinux/p/5677068.html
Copyright © 2011-2022 走看看