[自用6.]C++动态内存常见错误总结

1.申请的内存多次释放

#include <iostream>
using namespace std;

int main(){
    int * p = new int[18];
    p[0] = 0;
    char *p1 = NULL;
    //... ...
    //... ...
    delete[] p;//只允许一次释放
    //... ...
    //... ...
    delete[] p;//申请的内存多次释放, 程序出现异常

    system("pause");
    return 0;
}

 解决方案:在开辟新内存的时候就写好释放内存语句,其他语句在这两句语句的中间编写,养成这样的习惯,可以最大化避免重复释放内存

2.内存泄漏

#include <iostream>
using namespace std;

int main(){
    int * p = new int[18];
    p[0] = 0;
    char *p1 = NULL;

    //2. 忘记 delete,内存泄漏
    do{

    }while(1==1);
    

    system("pause");
    return 0;
}

运行结果:

解决方法同1.

3.释放的内存不是申请时的地址

#include <iostream>
using namespace std;

int main(){
    int * p = new int[18];
    p[0] = 0;
    char *p1 = NULL;

    //3.释放的内存不是申请时的地址
    for(int i=0; i<18; i++){
        cout<<*(p++)<<endl;
    }
    delete [] p;

    system("pause");
    return 0;
}

运行结果

解决方法:在动态分配内存的时候,尽量不要使用指针++的方法来进行操作,可以使用比较常规的p[i],如下

#include <iostream>
using namespace std;

int main(){
    int * p = new int[18];
    p[0] = 0;
    char *p1 = NULL;

    //3.释放的内存不是申请时的地址
    for(int i=0; i<18; i++){
        cout<<p[i]<<endl;
    }
    delete [] p;

    system("pause");
    return 0;
}

运行结果

4.释放空指针

#include <iostream>
using namespace std;

int main(){
    int * p = new int[18];
    p[0] = 0;
    char *p1 = NULL;

    //4.释放空指针
    // ... ...
    if(1==0){ //比如文件能打开的情况
    p1 = new char[2048];
    }
    //... ...
    delete p1;//如果文件没有打开,则p1是空指针
    

    system("pause");
    return 0;
}

运行结果:有时不会出问题,但有时会出问题,所以有风险,这个行为本身是不可取的

解决方法:可以将删除的语句放到if语句的里面,哪里使用就在哪里释放。在上面这段代码中,内存空间是在if语句中分配的,所以按照第一种情况给出的方法,删除语句应该也在if语句的大括号中出现。

5.释放一个内存块,但继续引用其中的内容

#include <iostream>
using namespace std;

int main(){
    int * p = new int[18];
    p[0] = 0;
    char *p1 = NULL;

    //5.释放一个内存块,但继续引用其中的内容
    delete[] p;
    // ...继续码代码...
    p[0]= '\0';//绝对禁止

    system("pause");
    return 0;
}

解决方法:暂时没想到很好的解决方法,尽量记住自己释放内存的位置,或者在保证安全的情况之下,尽量将要编写的语句放在释放语句的上面。也就是说,在编程的时候就在分配内存和释放内存两行代码的中间进行编写。

6.越界访问

#include <iostream>
#include <stdlib.h>
#include <cstring>
using namespace std;

int main(){
    int * p = new int[18];
    p[0] = 0;
    char *p1 = NULL;

   //6.越界访问
    memset(p, 0, 18*sizeof(int));
    for(int i=0; i<18; i++){
    cout<<*(p++)<<endl;
    }
    //误判
    for(int i=0; i<18; i++){
        cout<<*(p++)<<endl;
    }

    system("pause");
    return 0;
}

 运行结果:

解决方法:同3.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值