0%

空指针、野指针与悬垂指针

空指针

空指针:指针指向的地址为空的指针叫空指针/NULL指针

1
2
3
4
5
int *p1;
p1 = NULL;

char *p2;
p2 = NULL;

野指针

当所指向的对象被释放或者收回,但是对该指针没有作任何的修改,以至于该指针仍旧指向已经回收的内存地址,此情况下该指针便称悬垂指针(也叫迷途指针)。
某些编程语言允许未初始化的指针的存在,而这类指针即为野指针。

1
2
3
4
5
6
int a = 1;
int *p1; //这里p1没有初始化的赋值,随机只想一个地址,是野指针
p1 = &a; //指向了值

// 指针在申请的时候一定要赋值,至少要给NULL!
char *p2 = NULL;

悬垂指针

悬垂指针:指针所指向的对象已经被释放或者回收了,但是指向该对象的指针没有作任何的修改,仍旧指向已经回收的内存地址。 此类指针称为垂悬指针。

1
2
3
4
5
6
7
8
{
char *dp = NULL;
{
char c;
dp = &c;
} /* c falls out of scope */
/* dp is now a dangling pointer */
}

一个很常见的失误是返回一个栈分配的局部变量:一旦调用的函数返回了,分配给这些变量的空间被回收,此时它们拥有的是“垃圾值”。

1
2
3
4
5
6
int *func(void)
{
int num = 1234;
/* ... */
return #
}

调用 func 后,尝试从该指针暂时能读取到正确的值(1234),但是再次调用函数后将会重写栈为 num 分配的的值,再从该指针读取的值就不正确了。如果必须要返回一个指向 num 的指针,num 的作用域必须大于这个函数——它也许被声明为 static。

避免悬垂指针错误

在 C/C++ 中,一种最简单的技术是实现一个 free()(或类似的)替代版本或者 delete 析构器来保证指针的重置。然后,这个技术不会清除其他指针变量,它们含有该指针的副本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* Alternative version for 'free()' */
void safefree(void **pp)
{
if (pp != NULL) { /* safety check */
free(*pp); /* deallocate chunk, note that free(NULL) is valid */
*pp = NULL; /* reset original pointer */
}
}

int f(int i)
{
char *p = NULL, *p2;
p = (char *)malloc(1000); /* get a chunk */
p2 = p; /* copy the pointer */
/* use the chunk here */
safefree(&p); /* safety freeing; does not affect p2 variable */
safefree(&p); /* this second call won't fail */
char c = *p2; /* p2 is still a dangling pointer, so this is undefined behavior. */
}
-------------本文结束感谢您的阅读-------------