free后指针为NULL?
2016-10-11 15:56
288 查看
别看 free 和delete 的名字恶狠狠的(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。
用调试器跟踪示例程序,发现指针p 被free 以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,p 成了“野指针”。如果此时不把p 设置为NULL,会让人误以为p 是个合法的指针。
如果程序比较长,我们有时记不住p 所指的内存是否已经被释放,在继续使用p 之前,通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if 语句起不到防错作用,因为即便p 不是NULL 指针,它也不指向合法的内存块。
char *p = (char *) malloc(100);
strcpy(p, “hello”);
free(p); // p 所指的内存被释放,但是p 所指的地址仍然不变
…
if(p != NULL) // 没有起到防错作用
{
strcpy(p, “world”); // 出错
}
函数体内的局部变量在函数结束时自动消亡。很多人误以为示例7-6 是正确的。理由是p 是局部的指针变量,它消亡的时候会让它所指的动态内存一起完蛋。这是错觉!
void Func(void)
{
char *p = (char *) malloc(100); // 动态内存会自动释放吗?
}
上述例子,试图让动态内存自动释放
我们发现指针有一些“似是而非”的特征:
(1)指针消亡了,并不表示它所指的内存会被自动释放。
(2)内存被释放了,并不表示指针会消亡或者成了NULL 指针。
如何杜绝野指针?
“野指针”不是NULL 指针,是指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为用if 语句很容易判断。但是“野指针”是很危险的,if 语句对它不起作用。
“野指针”的成因主要有两种:
(1)指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL 指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如
char *p = NULL;
char *str = (char *) malloc(100);
(2)指针p 被free 或者delete 之后,没有置为NULL,让人误以为p 是个合法的指针。如上述第一个程序
(3)指针操作超越了变量的作用范围。这种情况让人防不胜防,示例程序如下:
class A
{
public:
void Func(void){ cout << “Func of class A” << endl; }
};
void Test(void)
{
A *p;
{
A a;
p = &a; // 注意 a 的生命期
}
p->Func(); // p 是“野指针”
}
函数 Test 在执行语句p->Func()时,对象a 已经消失,而p 是指向a 的,所以p 就成了“野指针”。但奇怪的是我运行这个程序时居然没有出错,这可能与编译器有关。
用调试器跟踪示例程序,发现指针p 被free 以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,p 成了“野指针”。如果此时不把p 设置为NULL,会让人误以为p 是个合法的指针。
如果程序比较长,我们有时记不住p 所指的内存是否已经被释放,在继续使用p 之前,通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if 语句起不到防错作用,因为即便p 不是NULL 指针,它也不指向合法的内存块。
char *p = (char *) malloc(100);
strcpy(p, “hello”);
free(p); // p 所指的内存被释放,但是p 所指的地址仍然不变
…
if(p != NULL) // 没有起到防错作用
{
strcpy(p, “world”); // 出错
}
函数体内的局部变量在函数结束时自动消亡。很多人误以为示例7-6 是正确的。理由是p 是局部的指针变量,它消亡的时候会让它所指的动态内存一起完蛋。这是错觉!
void Func(void)
{
char *p = (char *) malloc(100); // 动态内存会自动释放吗?
}
上述例子,试图让动态内存自动释放
我们发现指针有一些“似是而非”的特征:
(1)指针消亡了,并不表示它所指的内存会被自动释放。
(2)内存被释放了,并不表示指针会消亡或者成了NULL 指针。
如何杜绝野指针?
“野指针”不是NULL 指针,是指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为用if 语句很容易判断。但是“野指针”是很危险的,if 语句对它不起作用。
“野指针”的成因主要有两种:
(1)指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL 指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如
char *p = NULL;
char *str = (char *) malloc(100);
(2)指针p 被free 或者delete 之后,没有置为NULL,让人误以为p 是个合法的指针。如上述第一个程序
(3)指针操作超越了变量的作用范围。这种情况让人防不胜防,示例程序如下:
class A
{
public:
void Func(void){ cout << “Func of class A” << endl; }
};
void Test(void)
{
A *p;
{
A a;
p = &a; // 注意 a 的生命期
}
p->Func(); // p 是“野指针”
}
函数 Test 在执行语句p->Func()时,对象a 已经消失,而p 是指向a 的,所以p 就成了“野指针”。但奇怪的是我运行这个程序时居然没有出错,这可能与编译器有关。
相关文章推荐
- free()之后,显式的将指针置为NULL问题
- free之后将指针置为NULL
- 【C/C++学院】0820-Nullptr/const对象/类指针引用以及mallocfree与newde/类重载运算符/QT加法重载/类的重载赋值运算/自增在前在后差别/赋值重载深浅拷贝/重载下标
- 指针初始化是非常重要的,当我们在声明一个指针的时候请记得给它赋初值NULL,free释放完指针内容的时候也给他赋null初值。谢谢
- C 语言:指针、free()与 NULL
- c/c++中delete/free 指针后,设置p=NULL的好处
- 内存出错有时候是free后没有给指针赋NULL
- 空指针、NULL指针、野指针
- 空指针问题(java.lang.NullPointerException)
- Android6.0,7.0权限检测授权后报奇怪的null指针
- 对于一颗完全二叉树,要求给所有节点加上一个pNext指针,指向同一层的相邻节点;如果当前节点已经是该层的最后一个节点,则将pNext指针指向NULL;给出程序实现,并分析时间复杂度和空间复杂度。
- free(p)后指针问题
- 空指针问题(java.lang.NullPointerException)
- C/C++中利用空指针(NULL),提高程序运行效率
- NULL指针、零指针、野指针
- 【C/C++学习】之十六、关于空指针NULL、野指针、通用指针
- NULL 空指针 野指针
- 再谈野指针问题Free Heap block xxx modified at xxx after it was freed
- free 和 delete 把指针怎么了
- C语言之free函数及野指针