空指针NULL、野指针、通用指针

本文详细解释了C语言中指针的基本概念,包括指针变量的定义、初始化及其用途。同时深入探讨了空指针的概念,以及如何避免野指针导致的程序错误。

首先说一下什么是指针,只要明白了指针的含义,你就明白null的含义了。
假设 有语句 int a=10;
那么编译器就在内存中开辟1个整型单元存放变量a,我们假设这个整型单元在内存中的地址是 0x1000;那么内存0x1000单元中存放了数据10,每次我们访问a的时候,实际上都是访问的0x1000单元中的10.
现在定义:int *p;
                 p=&a;
当编译器遇到语句int *p时,它也会在内存中给指针变量p分配一个内存单元,假设这个单元在内存的编址为0x1003;此时,0x1003中的值是不确定的,(因为我们没有给指针赋值),当编译器遇到了p=&a时,就会在0x1003单元中保存0x1000,请看,这就是说:(指针变量p代表的)内存单元0x1003存放了变量a的内存地址!用通俗的话说就是p指向了变量a。
p=NULL,就是说:内存单元0x1003不存放任何变量的内存地址。

删除一个new了的数组。有必要的话。比如非标准的类( new CMyClass),在Type *p = new Type[N]; delete []p;的最后最好再加一句:   p = NULL

空指针是一个特殊的指针值,也是唯一一个对任何指针类型都合法的指针值。指针变量具有空指针值,表示它当时处于闲置状态,没有指向有意义的东西。空指针用0表示,C语言保证这个值不会是任何对象的地址。给指针值赋零则使它不再指向任何有意义的东西。为了提高程序的可读性,标准库定义了一个与0等价的符号常量NULL.    程序里可以写 p = 0;     或者 p = NULL; 两种写法都把p置为空指针值。相对而言,前一种写法更容易使读程序的人意识到这里是一个指针赋值。

我们印象中C语言的指针都有类型,实际上也存在一种例外。这里涉及到通用指针,它可以指向任何类型的变量。通用指针的类型用(void *)表示,因此也称为void 指针。
int n=3, *p;
void *gp;
gp = &n;
p=(int *)gp1;

野指针,也就是指向不可用内存区域的指针。通常对这种指针进行操作的话,将会使程序发生不可预知的错误。 
“野指针”不是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”); // 出错 

另外一个要注意的问题:不要返回指向栈内存的指针或引用,因为栈内存在函数结束时会被释放。见:http://hi.baidu.com/laodun/blog/item/eb8eb619c131414742a9adb0.html

可参考:http://hi.baidu.com/superluo/blog/item/68f1e703daaa73ea08fa9329.html

 

转载地址:http://apps.hi.baidu.com/share/detail/30190935

<think>首先,用户的问题是:“我想了解空指针和空类型指针的相关信息 请问空指针和空类型指针的概念、使用及区别”。我需要基于提供的引用内容来回答。 回顾系统级指令: - 所有行内数学表达式使用 `$...$` 格式。 - 独立公式使用 `$$...$$` 格式并单独成段。 - LaTeX 语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如 `[^1]`。 - 最后,回答结构清晰,帮助用户逐步解决问题,保证真实可靠。 提供的引用: - 引用[1]: 讨论了空指针和空类型指针空指针是存储 NULL指针,不能解引用。空类型指针是 void 指针。 - 引用[2]: 讨论了 C++11 中的 nullptr,作为空指针的替代。 - 引用[3]: 涉及指针数组和数组指针。 - 引用[4]: 讨论了常量指针指针常量。 用户的问题集中在空指针和空类型指针(即 void 指针)的概念、使用和区别。所以,我应该专注于引用[1]和[2]的相关部分。 关键点: - **空指针 (NULL pointer)**: 是指存储 NULL 值的指针,表示指针指向任何有效的内存地址。解引用空指针会导致错误,因为 NULL 地址未被分配。 - **空类型指针 (void pointer)**: 在引用[1]中提到“空类型指针”,可能指的是 void 指针,它是一种通用指针类型,可以指向任何数据类型,但不能直接被解引用;必须先被类型转换。 - **nullptr**: 在 C++11 中引入,用于表示空指针,避免了 NULL 的一些歧义。 从引用[1]: - "空指针是不能被解引用的,因为NULL地址指向的那块空间,没有分配给操作者使用,一但对NULL地址进行解引用,程序就会报错。" - "空类型指针: [^1]" – 这里似乎不完整,但结合上下文,应该是指 void 指针。 在 C/C++ 中: - **空指针**: 指设置为 NULLnullptr 的指针。 - **void 指针**: 是一种指针类型,可以指向任何数据类型。 区别: - 空指针是一个值(NULLnullptr),表示指针无效。 - void 指针是一个类型(void *),表示它可以指向任何类型的数据。 在回答中,我需要结构化: 1. **概念**: 解释空指针和空类型指针的定义。 2. **使用**: 如何声明、初始化和使用它们。 3. **区别**: 强调它们的差异。 生成相关问题:在回答结束后,添加相关问题,类似示例中的“§§相关问题§§”。 使用中文回答。 确保 LaTeX 正确:由于问题涉及指针,可能没有太多数学表达式,但我可以用 LaTeX 表示指针类型,如 `int *p = NULL;`。 参考引用: - 引用[1] 提到空指针和空类型指针。 - 引用[2] 提到 nullptr。 - 引用[3] 和 [4] 可能不直接相关,但如果有联系,可以提及。 结构化回答: 1. **空指针的概念**: 指针存储 NULLnullptr。 2. **空类型指针的概念**: void 指针的概念。 3. **使用**: 如何安全使用空指针,避免解引用;如何使用 void 指针进行泛型编程。 4. **区别**: 空指针是值,void 指针是类型。 添加引用标识:例如,当引用[1]的信息时,添加 ``。 生成相关问题: 1. 如何避免解引用空指针? 2. 在 C++ 中,nullptr 比 NULL 有什么优势? 3. void 指针在什么场景下使用? </think> ### 空指针与空类型指针的概念、使用及区别 在 C/C++ 编程中,空指针和空类型指针是两个重要的概念。它们都与指针的“空”状态相关,但含义和用途截然不同。下面我将基于提供的引用内容,逐步解释它们的概念、使用方法及主要区别,确保回答真实可靠。 #### 1. **空指针 (NULL Pointer)** - **概念**: 空指针是指存储特殊值 `NULL` 或 `nullptr` 的指针,表示该指针指向任何有效的内存地址。`NULL` 通常定义为 `0`(在 C 语言中),而 `nullptr` 是 C++11 引入的专门表示空指针的关键字。空指针不能被解引用(即访问其指向的数据),因为 `NULL` 地址对应的内存空间未被分配给程序使用,解引用会导致程序崩溃或未定义行为[^2]。 - 例如:一个整数指针可以声明为空指针:`int *p = NULL;`。此时,`p` 存储的是 `NULL`,而不是有效地址。 - **使用**: - **初始化**: 声明指针时赋值为 `NULL` 或 `nullptr`,避免“指针”(未初始化的指针)。这在 C++11 中更安全地使用 `nullptr`,因为 `NULL` 在 C++ 中可能被定义为整型常量,导致类型推断问题[^2]。 ```c int *p = NULL; // C 语言风格 int *q = nullptr; // C++11 风格,更安全 ``` - **检查与避免解引用**: 在使用指针前检查是否为空,防止运行时错误。 ```c if (p != NULL) { // 安全解引用 printf("%d\n", *p); } else { printf("指针为空,不能解引用\n"); } ``` - **应用场景**: 常用于函数参数检查(如返回空指针表示失败)或链表/树结构中的终止条件(如链表尾节点的 `next` 指针为空)。 #### 2. **空类型指针 (Void Pointer)** - **概念**: 空类型指针,也称为 `void` 指针(如 `void *ptr`),是一种通用指针类型,可以指向任何数据类型(如 `int`、`float` 或自定义结构体)。但 `void` 指针本身不能被直接解引用,因为它没有关联的具体数据类型,必须先通过强制类型转换(casting)指定目标类型后才能访问数据[^3]。 - 例如:`void *vp = &some_variable;` 表示 `vp` 可以指向任意变量,但操作前需转换。 - **使用**: - **声明与赋值**: 用于泛型编程或内存管理函数(如 `malloc`),能灵活指向不同数据类型。 ```c int a = 10; float b = 3.14; void *vp = &a; // 指向 int vp = &b; // 现在指向 float ``` - **类型转换与解引用**: 必须先转换为具体类型指针才能访问数据。 ```c // 转换后解引用 float *fp = (float *)vp; // 强制类型转换 printf("%f\n", *fp); // 输出 3.14 ``` - **应用场景**: 常用于动态内存分配(如 `void *malloc(size_t size)`)、回调函数接口或数据结构(如通用数组),因为它能处理任意数据类型。 #### 3. **空指针与空类型指针的主要区别** - **本质不同**: - **空指针** 是一个指针值(存储 `NULL` 或 `nullptr`),表示“无效地址”。它可以是任何指针类型(如 `int*`、`float*`),但值表示空状态。 - **空类型指针** 是一个指针类型(`void*`),表示“通用地址容器”。它存储有效地址,但类型未定,需转换后才能使用。 - 关键区别:空指针强调“值无效”,空类型指针强调“类型未知”[^1]。 - **解引用行为**: - 空指针:解引用会导致程序错误(如段错误),因为它指向未分配内存。 - 空类型指针:不能直接解引用,但转换类型后可以安全访问数据(前提是地址有效)。 - **使用场景对比**: - 空指针:用于错误处理或表示“无数据”状态(如函数返回空指针说明操作失败)。 - 空类型指针:用于跨类型数据操作(如内存拷贝函数 `memcpy` 使用 `void*` 参数)[^3]。 #### 4. **安全注意事项** - **避免解引用空指针**: 总是检查指针是否为 `NULL` 或 `nullptr` 后再使用。C++11 的 `nullptr` 比 `NULL` 更安全,因为它有明确的指针类型,避免整型转换歧义[^2]。 - **谨慎使用 void 指针**: 强制类型转换时需确保目标类型正确,否则可能引发未定义行为。例如: ```c void *vp = malloc(sizeof(int)); // 分配内存 if (vp != NULL) { int *ip = (int *)vp; // 正确转换 *ip = 42; // 安全赋值 } ``` 通过理解这些概念,您可以更安全地管理指针,防止常见错误如内存访问冲突。如需深入,可参考 C/C++ 标准库文档。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值