指针部分释疑之二:内存的分配及内存错误类型(续)

本文详细介绍了C++中常见的七种内存泄漏类型及其表现形式,并通过具体的代码示例进行了说明。此外,还针对其中一种内存泄漏类型提供了有效的解决方案。

4.常见的内存使用故障

内存泄露故障(Memory Leak FaultsMLF)是指在程序的某处申请了大小为X字节的空间,方式程序结束时这X字节的空间全部或部分没有释放、多次释放都属于内存泄露故障。

MLF有三种形式:

(1) 遗漏故障:申请的内存没有释放;

(2) 不匹配故障:申请函数和释放函数不匹配;

(3) 不相等的释放:释放的空间和申请的空间大小不一样。

C++中,MLF有以下表现形式:

þ 第一类MLF:在程序中申请了内存,但没有去释放

void main()

{

int *p;

p = new int[20];

for(int i = 0;i < 20;i++)

cin>>*(p + i);

for(int i = 0;i< 20;i++)

cout<<p[i];

return;

}

在程序中为p申请了内存空间,但是使用完成后没有去释放,即第一类MLF

þ 第二类MLFp是用malloc分配的变量,若存在且只有一个free(p),那么p的使用是正确的。反之,如果存在两个或两个以上free(p),或者无free(p),或者存在一个或一个以上的delete p,则称为第二类MLF

int *p = (int *)malloc(10*sizeof(int));

......

delete []p;

þ 第三类MLFp是用new分配的变量,若存在且只有一个delete p;,那么p的使用是正确的。反之,如果存在两个或两个以上delete p,或者无delete p,或者存在一个或一个以上的free(p),则称为第三类MLF

int *p = new int[10];

......

free(p);

þ 第四类MLFp是用new[]分配的变量,若存在且只有一个delete[],则p的使用是正确的。反之,如果用deletefree释放,则是第四类MLF

class A{ }; p = new A[10];

......

delete p;

þ 第五类MLF:多余的deletefree是第五类MLF

char *p = “abc”;

......

free(p);

þ 第六类MLF:当申请内存的p发生变化后,用deletefree释放变化后的p是第六类MLF

char *p = new char[10];

......

++p;

......

delete []p;

þ 第七类MLF;如果在构造函数中有申请内存的操作,且在其他函数中出现对象的拷贝,如果无拷贝(复制)构造函数,则会产生析构函数对内存重复释放的错误。该类错误为第七类MLF

#include <iostream.h>

#include <string.h>

class Stu{

public:

Stu(char *n,int a) //构造函数

{

name = new char[10];

strcpy(name,n);

age = a;

}

void Show() //输出函数

{

cout<<"The studnet's name is:"<<name<<endl;

cout<<"The student's age is:"<<age<<endl;

}

~Stu( ) //析构函数

{

delete []name;

}

private:

char *name; //学生姓名

int age; //学生年龄

};

void main( )

{

Stu s1("John",20); //定义对象s1

s1.Show();

Stu s2(s1); //s1初始化对象s2

s2.Show();

}

上述程序在执行的时候会输出:

The studnet's name is:John

The student's age is:20

The studnet's name is:John

The student's age is:20

然后会弹出:“Debug Assertion Failed!”的错误对话框,原因就在于用对象s1初始化s2的时候系统调用了系统提供的默认拷贝构造函数,只是将s1的指针变量name的内容(即地址)传送给了s2的指针变量name,那么s1s2name指向的是同一个空间,在主函数执行结束后,系统先析构s2,这是就将s2的指针变量name指向的空间释放了,然后系统析构s1的时候就会出现重复释放同一空间的情况,这就是第七种MLF

对于上述问题,解决方法就是定义用户给出的拷贝构造函数:

Stu(const Stu &p)

{

if(!name)

delete []name;

name = new char[10];

strcpy(name,p.name);

age = p.age;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值