编译C语言程序时,程序出现异常退出,好多情况都是因为使用指针出了问题:
易错情形一:指针没有初始化,就直接使用
struct stu{
int age;
string name;
};
struct stu* mm;
mm->age = 1;
mm->name = "xiaoming";
以上未对指针mm进行初始化,就为变量赋值出错,原因:未初始化的指针,没有申请内存空间,故成员变量age,name没有空间存储
改正:
struct stu{
int age;
string name;
};
struct stu* mm = new struct stu;
mm->age = 1;
mm->name = "xiaoming";
易错情形二:指针动态初始化后,用完后,未释放new的空间
struct stu{
int age;
string name;
};
struct stu* mm = new struct stu;
mm->age = 1;
mm->name = "xiaoming";
//do sth.
delete mm;//一定不要忘了释放内存
mm = NULL;
易错情形三:当指针初始化与释放指针分别置于不同的函数时,释放指针时未做判断
struct stu{
int age;
string name;
};
class CSTU{
private:
struct stu* mm;
public:
CSTU();
~CSTU();
foo();
freeBuf();
};
CSTU::CSTU{
mm = NULL;//这个地方一定要对指针进行初始化
}
CSTU::~CSTU{
}
CSTU::foo()
{
mm = new struct stu;
mm->age = 1;
mm->name = "xiaoming";
}
CSTU::freeBuf()
{
if(mm)//这个地方一定要判断一下,倘若mm没有new空间,直接delete会出错。
{
delete mm;
mm = NULL;
}
}
void main()
{
CSTU mm;
int i = 10;
while(i--)
{
mm.foo();
mm.freeBuf(); //这个地方一定要与foo配合使用,每次都要进行delete
}
}
以上程序注意几点:
1)指针初始化的函数与释放函数不为同一函数时(此时,一般指针成员变量会多次进行初始化),首先两个函数一定要配合使用,其次,释放函数时,一定要对指针的值进行判断(因为,freeBuf调用前,可能没有调用初始化函数foo,这就要求,构造函数中对指针需要先置NULL,否则直接freeBuf,也会因为指针没有赋值而出错),避免指针没有new,而被释放,导致出错。
2)类成员变量有指针的时候,在类构造函数中一定要先初始化,比如初始化为NULL(多次使用)或者直接new空间(单次使用)
3)当类成员变量只初始化一次时,我们可以在构造函数中进行new空间,在析构函数中释放指针。,如下所示:
struct stu{
int age;
string name;
};
class CSTU{
private:
struct stu* mm;
public:
CSTU();
~CSTU();
};
CSTU::CSTU{
mm = new struct stu;
mm->age = 1;
mm->name = "xiaoming";
}
CSTU::~CSTU{
delete mm;
mm = NULL;
}
void main()
{
CSTU mm;
cout<<mm->age<<mm->name;
}
上述程序,指针成员变量只在构造函数中进行初始化一次,
所以在析构函数中析构时,不必对其值进行判断(当然判断一下是否为空,是一个好习惯)
小结:使用指针时,一定要进行初始化,指针用完后,一定要进行释放;
类成员为指针时,构造函数中一定要对指针进行初始化!!!!!!(看情况初始化为NULL,或直接new )
指针进行释放前,最好进行判断是否为非NULL。
易错情形四:函数内使用的参数为指针时未做判断、函数的返回值未指针时,使用函数未做判断
//函数内部,使用是指针的参数时要做判断
void foo(char *pt)
{
if(!pt)
return; //函数内部使用指针时,进行判断是否为空
//do sth.
}
char *p = NULL;
p = new char;
*p = 100;
foo(p);
//函数的返回值为指针,使用函数时要做判断
char* foo(int i)
{
char *p = NULL;
if(i)
{
return NULL;
}else{
p = new char;
*p = 100;
return p;
}
char* ptr = foo();
if(!ptr)
{
cout<<"正常";
}