本文已参与「新人创作礼」活动,一起开启掘金创作之路。 如果你喜欢这个系列,欢迎点赞收藏关注评论。文章若有错误或是不合适的地方欢迎指正,我们一起进步 : -)
你到底是谁?指针数组 与 数组指针 的区别
指针数组:
本质是一个数组,一个指针的数组
声明
char *arr[4]
/* 等价于 */
char *(arr[4])
解释
arr是一个数组arr数组包含4个元素- 每个数组元素是一个char *类型的指针
- 每个指针存放着对应字符的首地址
数组指针:
本质是一个指针,一个数组的指针
声明
char (*pa)[4] /* pa即 Pointer of Array */
解释
pa是一个指针pa指向一个char [4]的数组- 每个数组元素是一个char类型的变量
空指针的迷思——我指向空,但我不为空
空指针 (Null Pointer)是一个已宣告、但并未指向一个有效对象的指针
那么,让我们试着思考一个脑筋急转弯:当指针所指地址上为空值时,指针为NULL吗?
正确答案: 不 更具体的说: 一个非NULL的指针所指向的地址,该地址上可以是空值(NULL) 但是一个指针一旦被成功分配了(指向)某块内存空间,那么不论这块内存空间上有没有数据,该指针都不为NULL 举个栗子🌰:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* NULL 是被定义在 _types.h 中的: #define __DARWIN_NULL ((void *)0)
* 一个指针,只要被分配了内存空间,那么它就不为NULL;
* 只有内存分配失败(内存已满,没有空间再分配)的时候,该指针才会为 NULL
*/
int main()
{
char *str;
// 给 str 分配内存空间
// 合理的内存分配
str = (char *)malloc(20);
// str = (char *)malloc(2147483647); // 2^31 - 1 = 2147483647, the max value of a 32-bit signed integer
// 超大的内存请求
// str = (char *)malloc(421341234232345); // failed
// str = (char *)malloc(9223372036854775807); // 2^63 - 1= 9223372036854775808, the max value of a 64-bit signed integer
// strcpy(str, "hello world");
// 如果指针为空
if (str == NULL)
{
printf("分配内存失败!str 指针仍为 NULL\n");
return 0;
}
else
{
// 如果指针不为空,打印指针所指位置的内容
printf("String content = \"%s\", Address = %u.\n", str, str); // 此时虽然指向的内容是空字符串,但指针不为 NULL
// free the pointer
free(str);
}
return (0);
}
在上面这段代码中: 如果14/15行被执行,则会运行到第29行,打印字符串内容和地址,此时虽然指向的内容是空字符串,但指针不为 NULL 如果17/18行被执行,则会运行到第23行,提示你str指针并没有被成功分配空间,它仍然是一 个NULL Pointer
目前我接触到操作系统的源码中,经常使用【为指针申请内存-判断指针是否为NULL】这套连招,来判断是该进程否成功申请到内存。如果没有,则返回相应的 error code
野指针——心里有了不该有的人,是谁我不说
野指针是一个指向不可用内存区域的指针。通常对这种指针进行操作的话,将会使程序发生不可预知的错误。就好像你爱上了一个不该爱的人,如果表白了,你的生活会变的一团糟。
野指针不是NULL指针,而是指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为用if语句很容易判断。但是“野指针”是很危险的,if语句对它不起作用。野指针的成因主要有两种:
- 指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。
- 指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。别看free和delete的名字恶狠狠的(尤其是delete),它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if语句起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。例如:
char *p = (char *) malloc(100); strcpy(p, “hello”); free(p); // p 所指的内存被释放,但是p所指的地址仍然不变 if(p != NULL) // 没有起到防错作用 strcpy(p, “world”); // 出错