c 释放两次内存_从缺陷中学习C/C++:聊聊 C++ 中常见的内存问题

本文详细讨论了C/C++编程中的内存问题,包括内存泄露、悬挂指针、数组越界、内存重复申请、变量作用域、指针传值与传址等多个方面。通过代码示例分析错误原因并提供解决方案,帮助开发者理解和避免这些常见的编程陷阱。
摘要由CSDN通过智能技术生成

在写C/C++程序时,一提到内存,大多数人会想到内存泄露。内存泄露是一个令人头疼的问题,尤其在开发大的软件系统时。一个经典的现象是,系统运行了10天、1个月都好好的,忽然有一天宕机了:

OOM(Out Of Memory,内存用光)!于是,痛苦地查找内存泄露根源的过程开始了…本拿主要讨论内存使用问题,包括内存泄露、悬挂指针、内存重复申请、变量的作用范围等,涉及指针、数组、引用等的使用。

6.1数组越界

代码示例

#define ARRAY_SIZE 1024char strArray(ARRAY_SIZE];strArray(ARRAY_SIZE]='0';

现象&结果

数组访问越界,程序运行崩溃。

Bug分析

C或C++中,数组的下标地址范围是从[0-(size-1),下标size已经超出了数组范围。

正确代码

#define ARRAY_SIZE 1024char strArray[ARRAY_SIZE];strArray(ARRAY_SIZE-1] ='0';

6.2数组定义和值初始化形式混淆

代码示例

int *ip = new int(12);for (inti=0;i<12;i++ ){ip[i]=i;}delete [] ip;

现象&结果

产生运行时错误,提示如下的错误信息:

glibc detected *** free() : invraid next size (fast)

Bug分析

int "ip=new int(12)表示new了一个整型变量,值是12, ip指向这个变量。

new返回的指针ip是in类型,不是一个数组指针,赋值的时候,采用数组的方式,造成越界访问内存,并且在结束的时候用deltel删除指针数组,造成程序崩渍。

解决方法是:把小括号改写成中括号。

正确代码

int* ip = new int(12];for (int i= 0; i< 12; i++){ip[i] =i;}delete [] ip;

6.3数组传参时的sizeof

代码示例

void copy(int a[], int b[]) {memepy (b, a, sizeof(a));}

现象&结果

copy函数执行后,内存中的内容与设想不符, 目标数组b中的内容不完整,没有把源数组a中的内容全部复制过来。

Bug分析

memepy函数的原型是void *memepy(void *dest, const void *src, size_tn);,它的功能是从源src所指的内存地址的起始位置开始复制n个字节到目标dest所指的内存地址的起始位置中。上述程序中, copy函数的两个形参悬数组a和数组b,函数体中调用了memcp函数,并且为memepy函数的第三个参数赋值sizeof(a)。程序的本意是期望sizeof(a)返回数组a所占的字节数,通过memcpy函数,把源数组a中的内容全部复制到目标数组b中。但是数组int a0作为copy函数的形参,在copy函数体内将退化成指针,所以, sizeof(a)返回的是指针的字节数,而不是数组a的字节数。因此,数组b中只是部分复制了数组a中的内容。解决办法是:在copy函数中增加一个参数,作为数组复制的字节数。

正确代码

void copr (int a[], int b[], int len) { memspy(a, b, sizeof(int)*1en);}void del (int a[], int len){ memset(a, 0, sizeof(int)* en);}

或者用数组的引用方式传参:

void copy(int a[], int (&b)[]) {memcpy(a, b, sizeof(b));}

编程建议

数组传递参数时,连同数组长度一起传入是一个好方法。或者用std::vector代替数组可以避免不必要的麻烦。使用数组的引用,作为函数的参数,也可以解决上面的问题。

6.4临时对象的生存期

代码示例

class MyString {public:MyString(){s_= (char *)malloc(strlen(str) + 1);strcpy (s_, str);}~MyString() {printf("destory n");}friend MyString operator+(const MyString &lstr, const MrString&rstr){size_t llen = strlen(lstr);size_t rlen = strlen(rstr);char buf[llen + rlen +1];strcpy (buf, Istr);strcat(buf, rstr)return MyString(buf);}operator const char *() const {//当string转换char时调用return_s}private:char* _s;};int main(){Mysting s1("hello"), s2( "wold!");const char*p=s1+s2;printi("%os n", p);return 0;}

现象&结果

程序运行时通常是正常的,但有时会出错,特别是在多线程时,会出现奇特的错误:例如,指针p指向的内容不是期望的内容。

Bug分析

错误出在main函数中的const char*p=s1+s2代码行处。程序会首先生成一个临时对象,用来存储

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值