执行析构函数时造成的野指针
当执行析构函数时,使用指针往往不注意会造成野指针,那是因为,产生匿名对象时,系统所提供的赋值构造函数只是执行简单的操作,特别是涉及到动态内存方面的操作,往往需要我们手工写赋值构造函数来避免这种弊端。例如执行下面的函数就会崩溃:
class Name
{
public:
Name(const char *myp)
{
int len = strlen(myp);
p = (char *)malloc(len+1);
strcpy(p,myp);
}
~Name()
{
if (p != NULL)
{
free(p);
p = NULL;
len = 0;
}
}
protected:
private:
char *p;
int len;
};
void objplaymain()
{
Name obj1("adcd");
Name obj2 = obj1;//会自行调用系统提供的赋值构造函数,产生匿名对象
}
void main()
{
objplaymain();
return;
}
当执行 strcpy(p,myp); 时,系统只是把myp的地址做了个拷贝,p并没有创建新的内存,其本质和myp的地址一样指向了同一块内存,
当执行完 void objplaymain()此函数后,会执行析构函数,析构的顺序是先执行后释放,当obj2对象先析构后,p和myp共同指向的内存被释放,而obj1对象后析构,但其内存被释放,从而产生野指针,后果是系统会崩溃。解决方法是给obj2也创建一个内存空间:
class Name
{
public:
Name(const char *myp)
{
len = strlen(myp);
p = (char *)malloc(len+1);
strcpy(p,myp);
}
Name(const Name& obj)
{
len = obj1.len;
p = (char *)malloc(len +1);
strcpy(p,obj1.myp);
}
~Name()
{
if (p != NULL)
{
free(p);
p = NULL;
len = 0;
}
}
protected:
private:
char *p;
int len;
};
void objplaymain()
{
Name obj1("adcd");
Name obj2 = obj1;//会自行调用系统提供的赋值构造函数,产生匿名对象
}
void main()
{
objplaymain();
return;
}
应当注意的是,对象的赋值操作如“obj2=obj1” 也可能会造成野指针,他不是系统自带赋值函数引起,但是只是执行简单的赋值,一旦释放内存,指针就会成为野指针,这点跟上面所讲类似。

浙公网安备 33010602011771号