• 常见动态内存错误---内存泄漏


    常见动态内存错误

    编译器不能自己主动发现动态内存错误,动态内存错误通常仅仅能在程序执行时才干被捕捉到,并且错误原因不easy查找,错误本身也不easy捕捉,改错难度较大。



    1.动态内存分配失败却继续操作
    内存不足等有可能导致动态内存分配失败,所以使用new请求分配动态内存后一定要检查返回地址是否为NULL。
    如用if(p==NULL) 或 if(p!=NULL)进行检查,未检查前不要操作动态内存空间。


    2.动态内存空间未初始化就进行读操作
    C++标准并未规定动态内存空间的默认值,程序无法预知该默认值的详细指。因此,未经初始化的动态内存空间可能持有一个不确定的值。
    所以申请分配动态内存空间的同一时候,要初始化该动态内存空间,尽量不要使用系统默认值。


    3.动态内存空间越界使用
    指针的功能尽管非常强,但它easy指向错误的地方。当指针指向不对的数据类型时,指针操作就会出错。
    尤其是当指针指向一个数组时,非常easy越界,造成错误。


    4.内存泄漏
    内存泄漏是一种比較严重的动态内存错误。程序长时间执行终于可能导致内存耗尽,执行速度变慢甚至系统奔溃。
    比如:new与delete使用不配对,就可能导致new的空间未被delete。
    使用new运算符申请分配的内存空间使用完后,一定要记得使用delete释放,且new形式要与delete相应。


    5.继续使用已经释放了的动态内存空间
    运行delete后,对应的指针变量的值未被改变,它依旧指向原来的动态内存空间,仅仅是原来动态内存空间的内容已经毫无意义了。

    所以在运行delete之后,通常要将指针变量的值置成NULL,以免对内存空间进行误操作或者无效操作。


    以下详细讲讲内存泄漏:


    内存泄漏

    指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。
    内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。 


    以下举几个样例:

    1.以下a先是申请了一个int型的动态内存空间,初始化值为12,后面a又申请了一个int型空间,初始化值为34,
    则第一次存储12的空间就不会被释放,而且存储12的空间没有被释放,也不能被使用了,造成了内存泄漏。

    #include<iostream>
    using namespace std;
    
    int main()
    {
    	int *a=new int (12);
    
    	cout<<*a<<endl;
    	         //须要 delete a;
    	a=new int (34);
    
    	cout<<*a<<endl;
    
    	delete a;
    
    	system("pause");
    	return 0;
    }
    2.以下的函数,当调用时,会在动态内存中创建一个char型数组,并在桟中生成一个char型指针变量pChar,用pChar指向该数组。
    当F调用结束时,pChar会自己主动消失,由于它位于桟区中,是局部变量;
    而长度为100的动态内存空间中的字符串数组却依旧存在,没有释放。
    所以退出F()后内存就泄漏了,并且每次调用都会造成新的泄漏。
    void F(void)
    {
    	char *pChar=new char [100];
    	//do something
    }
    最好的做法就是:

    void F(void)
    {
    	char *pChar=new char [100];
    	//do something
    
    	delete []pChar;
    }

    3.出现下面问题呢?

    //F返回一个指针,指向一个动态分配的对象
    int *F(T arg)
    {
       return new int [arg];//调用者负责释放此内存
    }

    返回指向动态内存的指针的函数给其调用者添加�了一个额外的负担---调用者必须记得释放内存


    4.delete仅仅提供了有限的保护

    看以下的样例:

    运行delete后,对应的指针变量的值未被改变,它依旧指向原来的动态内存空间,仅仅是原来动态内存空间的内容已经毫无意义了。
    所以在运行delete之后,通常要将指针变量的值置成NULL,以免对内存空间进行误操作或者无效操作。

    可是,

    int *p=new int (42);
    auto q=p;
    delete p;
    p=NULL;

    p和q指向同样的动态分配的对象,我们delete此内存,然后将p置为NULL,指出它不再指向不论什么对象。可是,重置p对q没有不论什么作用,在我们释放p所指向的(同一时候也是q所指向的)内存时,q也变得无效了。在实际系统中,查找指向同样内存的全部指针是异常困难的。

  • 相关阅读:
    想当老板的人,三点特征很重要(转)
    突破三个自我,你就不光是老板的料
    掌握这3套创业战略 保你赚到百万财富 
    也感山西黑窑洞
    再游府河有感
    朋友的影响力非常大,朋友决定你的财富
    夏日乘凉
    职业生涯的八大“定位法则”
    一生何求
    赠你一方明月
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4049772.html
Copyright © 2020-2023  润新知