c++ 关于new和delete的相关测试

不看源码的代价就是:只能在表象中猜内层结构

 

 

结论写在前头:

 1.使用  Type *pointer =new type 或者 Type *pointer =new type()方式都可以申请内存大小,后者调用默认构造函数进行内存初始化;但是,禁用自定义类以及默认类型,

去使用 Type result=Type()结构,编译器会认为这是函数声明而不是自定义类型对象;

 

 2.若使用new指定大小为0的数组对象时,无论有没有括号,不会申请内存,更不会进行初始化内存空间,其操作完毕后指向一个非nulltr空间,故,要注意不能对该指针进行成员操作

最好的预防方式就是申请时进行参数检查。另外,delete 和new操作要相互匹配,即使对空指针两种delete都有效,但是 空的数组对象(长度为0),也要用delete[]形式,而非delete

 

 3.c++new,只需指定数量,自动计算内存大小,失败会直接抛出bad alloc异常,不捕捉则直接terminate,故try...catch ....

   除非使用  Type **pointer =new (nothrow) type ,使用该操作就不会抛出异常,行为跟C类似;

    而c语言malloc需要之指定申请的大小,即不仅需要输入数量,还需要指定单个元素大小,失败时返回空指针,故使用c编写时要检查空指针

 

 

 

 

测试:

1.关于new 相关的自定义结构和默认类型的构造测试

    

 

2.new &delet空数组测试

   结论:如无必要,禁止new空数组,传入参数进行内存申请时最好检测下大小,而不是一来size_t类型做非负数保证,防止非法访存

 

 

 1 #include<iostream>
 2 using namespace  std;
 3 void result()
 4 {
 5     cout << "\n\n结论:" << endl;
 6     cout << "可以申请长度为0的数组,其理所当然的不会调用定义的析构函数以及构造函数,因为对象本来就没有\n但会产生未定义后果,因此应该对输入进行非正整数判定非法" << endl;
 7     cout << "否则,调用成员直接未定义,对成员进行改动则直接在析构时会产生无法预料的后果" << endl;
 8     cout << "要么析构调用内存报错,要么无理由程序完成,不析构则内存泄漏+非法访存\n故不要对非法地址进行对象操作,更准确的说应该避免构造空数组\n" << endl;
 9     cout << "另外,数组申请为0大小,delete []不会报错,对一个nullptr进行delete[]也不会报错,但直接delete会" << endl;
10 
11 
12 }
13 
14 class k {
15 public:
16     double a = 1;
17     double b;
18     k() { cout << "install" << endl; }
19     k(int x) :a(x) { cout << x << " install" << endl; }
20     k(const k&t) { a = t.a; }
21     k& operator=(const k&t) { a = t.a; }
22     ~k() { cout << "destroy" << endl; }
23     void changeA()
24     {
25         a = 3;
26         cout << "成功函数修改未定义" << endl;
27     }
28     void function(int x)
29     {
30         cout << x << "  function 即使是空对象也能调用成员函数" << endl;
31     }
32 };
33 
34 
35 int main()
36 {   //以下测试是在2019/8月进行,vs2017,win10,debug*86
37     k *fff = nullptr;
38     fff = new k[0];
39 
40     try {
41         if (fff == nullptr)cout << "this is a nullptr" << endl;
42         else
43         {
44             cout << "new k[0] 不返回一个空指针!!! " << endl;
45             //输出一个未定义的系统默认结构则不会退出
46             cout << "输出该指针指向的对象成员    a  :" << fff->a << endl;
47             //调用一个函数一样能运行
48             fff->function(3);
49             cout << "该指针指向结构大小  " << sizeof(*fff) << endl;
50             cout << "输出该指针指向数组的长度  :" << sizeof(fff) / sizeof(k) << endl;
51             //试图直接或者以函数接口改动未定义内存是非法的,不会在修改时报错或者不报错直接退出
52             fff->changeA();
53             fff->a = 4;
54             cout << "成功直接修改未定义值" << endl;
55 
56         }
57         //fff = nullptr;    //delete[]是合法的
58         delete[]fff;  //如果将上面的非法修改操作注释掉,delete[]fff 是合法且不报错的
59                     //如果将此析构删除,那么更会带来致命的后果,
60                     //即内存泄漏且非法写了未定义的内存而不报错
61         cout << "delete操作运行结束" << endl;  //无论是否弹出报错,该语句不会运行,因为程序delete后结束了
62     }
63     catch (exception e) {
64         cout << e.what() << endl;
65         //无法捕捉上诉修改未定义值后,析构的错误,直接退出
66     }
67     result();
68 }

 

 

 

 

 

 

 

 

 

3.测试自定义结构下是否跟基本类型一样,函数返回内存类型会不会造成内存泄漏

 

        测试方法为使用vs2017 debug功能依次监视各个阶段的内存占用,查看是否成功释放

 

 

 

 

       3.1.直接在代码中静态(直接写明)申请内存,以delete[] 的方式进行显式释放内存-----------------------------------结论:没有发生内存泄漏,内存成功释放

 

 

    3.2.直接在代码中静态(直接写明)申请内存,以直接delete 的方式进行显式释放内存------------------------------结论:没有发生内存泄漏

 

 

3.2.以调用函数的方式,类似静态返回指向内存的指针进行测试 ,并以直接delete的方式进行内存释放   --------------结论:没有发生内存泄漏

 

3.3; 以非静态大小的方式输入,进行函数返回并delte【】释放测试,测试结果  :依旧没有发生内存泄漏  

 

3.4 动态输入大小的方式进行调整,返回数组内存,使用delete方式进行测试 依旧没有发生内存泄漏

转载于:https://www.cnblogs.com/jing19960917/p/11401778.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值