一、野指针问题
1.1野指针概念
野指针是指向不可用内存的指针,与空指针不同,野指针无法通过简单地判断是否为NULL避免。
如果程序定义了一个指针,就必须要立即让它指向一个我们设定的空间或者把它设为NULL,如果没有这么
做,那么这个指针里的内容是不可预知的,即不知道它 指向内存中的哪个空间(即野指针),它有可能指向
的是一个空白的内存区域,可能指向的是已经受保护的区域,甚至可能指向系统的关键内存。所以我们必须
设定一个空间让指针指向它,或者把指针设为NULL,如果是建立一个与指针相同类型的空间,实际上是在内
存中的空白区域中开辟了这么一个受保护的内存空间,然后用指针来指向它,那么指针里的地址就 是这个受
保护空间的地址了,而不是不可预知的啦,然后我们就可以通过指针对这个空间进行相应的操作了;如果我
们把指针设为NULL,指针里的地址(机器数)就被初始化为0了,内存中地址为0 的内存空间地址是特定
的,指针就不是不可预知的野指针了。
free和delete只是把指针所指的 内存给释放掉,但并没有把指针本身干掉。指针p被free以后其地址仍然不变
(非NULL),只是该地址对应的内存是垃圾,p成了“野指针”。如果此时不 把p设置为NULL,会让人误
以为p是个合法的指针。用free或delete释放了内存之后,就应立即将指针设置为NULL,防止产生“野指
针”。内存 被释放了,并不表示指针会消亡或者成了NULL指针。
1.2 产生野指针的原因
产生野指针的主要原因有以下三点:
(1)指针变量未初始化
任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的。所以指针变量在创建的同时应当被
初始化,要么将指针设置为NULL,要么让它指向合法的内存。
(2)指针释放后之后未置空
有时指针在free或delete后未赋值 NULL,便会使人以为是合法的。别看free和delete的名字(尤其是
delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。此时指针指向的就是“垃
圾”内存。释放后的指针应立即将指针置为NULL,防止产生“野指针”。
(3)指针操作超越变量作用域
不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, “hello”);
free(str);
if(str != NULL)
{
strcpy(str, “world”);
printf(str);
}
以上的代码我们可以知道运行结果不可知,因为篡改动态内存区的内容,后果难以预料,非常危险。
free(str);之后,str成为野指针,if(str != NULL)语句不起作用,为了防止出现危险,应该在free之后应该将
str置空,修改后代码如下:
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, “hello”);
free(str);
str=NULL;
if(str != NULL)
{
strcpy(str, “world”);
printf(str);
}
二、如何防止野指针
2.1 malloc()和free()的基本概念以及基本用法:
void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分
配失败,则返回一个空指针(NULL)。
char *Ptr = NULL;
Ptr = (char *)malloc(100 * sizeof(char));
if (NULL == Ptr)
{
exit (1);
}
gets(Ptr);
void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了
这块内存,让它重新得到自由。
free(Ptr);
Ptr = NULL; //一定要记得Ptr置空,否则会成为野指针
free()释放的是指针指向的内存,不是指针。指针是一个变量,只有程序结束时才被销毁。释放了内存空间
后,原来指向这块空间的指针还是存在!只不过现在指针指向的内容的垃圾,是未定义的,所以说是垃圾。
2.2 使用函数注意事项
A、申请了内存空间后,必须检查是否分配成功。
B、当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向NULL,防止程序后面
不小心使用了它。
C、malloc与free以及c++中的new和delete函数应该是配对。如果申请后不释放就是内存泄露;如果无故释
放那就是什么也没有做。释放只能一次,如果释放两次及两次以上会 出现错误(释放空指针例外,释放空指
针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)。