当前位置: 首页 > news >正文

39.【C语言】指针(重难点)(D)

目录

10.野指针

定义

案例

随机的(没有初始化)

没有明确限制的(越界访问)

指针指向的空间释放

11.野指针规避方法

初始化

防止越界

指针变量不再使用时,及时置NULL,指针使用之前检查有效性

避免返回局部变量的地址

其实特殊情况下,空指针及空指针附近的内存区域是可以被访问的

13.assert() (assert v.断言)

解释

作用

优点

启用assert的开关

往期推荐


承接上篇 38.【C语言】指针(重难点)(C)

10.野指针

定义

指针指向的位置是不可知(随机的、没有明确限制的)

案例

随机的(没有初始化)

int* p; *p = 10;//非法访问

没有明确限制的(越界访问)

#include <stdio.h> int main() { int arr[10] = {0}; int* p = &arr[0]; for(int i=0; i<=11; i++) { *(p++) = i;//当i>=10时,p就是野指针 } return 0; }

注意:*(p++) = i;先使用,后++ --> *p = i; p++;

指针指向的空间释放

#include <stdio.h> int* test() { int n = 100; return &n; } int main() { int* p = test(); printf("%d\n", *p); return 0; }

分析:test函数定义的n的生命周期介于test函数的 { 与 } 之间,一旦出test函数,n交换给操作系统,没有使用权限,即空间释放

例如scanf("%d",a);会被报错,原因是野指针

11.野指针规避方法

初始化

明确知道指针指向哪里就直接赋值地址,如果不知道指针应该指向哪里,给指针赋值NULL(空指针)

int num = 10; int*p1 = &num; int*p2 = NULL;
#define NULL ((void *)0) //把0转换为(void *)

附: 空指针发明人Tony Hoare的演讲Null References: The Billion Dollar Mistake - InfoQ

内存查看p2的地址

注意:空指针不能访问(*p2=10;不允许),即不允许向地址为0处写入数据

注:在C++11之后,使用nullptr来代替了NULL

防止越界

int main() { int arr[10] = {1,2,3,4,5,6,7,8,9,10}; int* p = &arr[0]; int i = 0; for(i=0; i<10; i++) { *(p++) = i; } //p已越界,把p置为NULL p = NULL; return 0; }

指针变量不再使用时,及时置NULL,指针使用之前检查有效性

规则:只要是NULL指针就不去访问,同时使用指针之前可以判断指针是否为NULL

if (p2 != NULL) { dosomething; }

避免返回局部变量的地址

见本篇:指针指向的空间释放

其实特殊情况下,空指针及空指针附近的内存区域是可以被访问的

详见格友公众号文章谁说空指针不能访问的?

13.assert() (assert v.断言)

解释

assert(表达式);如果表达式为真(返回值非零),继续执行;如果表达式为假(返回值为零),则报错

作用

在运行时确保程序符合指定条件,如果不符合,就报错终止运行

使用前引用头文件

#include <assert.h>

优点

报错是会在窗口显示没有通过的表达式,以及包含这个表达式的文件名和行号

#include <assert.h> int main() { int* p = NULL; assert(p != NULL); return 0; }

运行结果:

启用assert的开关

禁用assert:在#include <assert.h>前加#define NDEBUG,可以提高程序的运行效率,尽管assert(表达式)为假,但不会报错,继续执行,

启用assert:直接注释掉#define NDEBUG

注:NDEBUG为No Debug


往期推荐

19.【C语言】指针(重难点)(A)

37.【C语言】指针(重难点)(B)

38.【C语言】指针(重难点)(C)

http://www.jsqmd.com/news/558160/

相关文章:

  • FastAPI数据库索引:复合索引优化查询性能的终极指南
  • BiliTools:跨平台哔哩哔哩资源管理革新方案,5大场景化技巧提升下载效率300%
  • 嵌入式硬件设计中常见英文缩写解析与应用
  • 导师严选!盘点2026年最强的的降AI率网站
  • 实战解析:WAF绕过技术全攻略(云盾、宝塔、安全狗)
  • Simula核心技术解析:Godot与Haskell如何构建VR窗口管理器
  • 手机拍照的“大脑”ISP是怎么工作的?深入拆解N段式统计法与卷帘快门那些事
  • 二极管选型实战指南
  • java中类的继承怎样理解 继承的概念和代码示例
  • 2000-2024年全国省份/地市/区县区划人口数据
  • 2026年热门的侧入式搅拌设备实力品牌厂家推荐 - 品牌宣传支持者
  • 告别DLSS版本迷宫:DLSS Swapper如何实现3步智能优化
  • 如何快速上手Zadig:5分钟完成第一个微服务部署
  • 中医针灸治疗颈肩腰腿痛,长春颈肩腰腿痛医院古法调理更温和
  • Java 25密封类扩展特性全曝光:从JDK源码级解读permits继承链与编译器校验增强
  • 【具身智能06】具身智能多模态感知与传感器融合:从看见到理解
  • 老旧设备焕新:用OpenCore Legacy Patcher开源工具突破macOS硬件限制方案
  • 为什么说Sigrity XtractIM是IC封装分析的利器?从SPICE到全波精度的全面解析
  • 2026年广西沃柑树苗优质供应商推荐榜:沃柑果苗、沃柑种苗、爱媛38果冻橙、四川春见耙耙柑、四川耙耙柑、广西武鸣沃柑选择指南 - 优质品牌商家
  • Photon OS 网络配置完全手册:从基础到高级应用
  • RK3566千兆以太网调优实战:如何手动配置RGMII延迟线(附泰山派开发板实测)
  • Hopf振荡器参数调优指南:如何为你的机器人‘定制’稳定节律信号
  • 深度学习YOLOv8手势识别系统+数据集+毕业论文
  • 3大核心技术破解字幕困境:Buzz工具智能优化全指南
  • 如何为 Play With Docker 贡献代码:社区参与与开发流程详解
  • 终极指南:如何让2015年前的MacBook Pro用上最新macOS系统
  • wedding自定义配置完全手册:图片素材、背景音乐与地图位置的个性化设置
  • 【具身智能07】具身智能世界模型与端到端架构:从看见到理解物理规律
  • 跨平台文件同步:OpenClaw调用Qwen3-32B镜像理解内容智能去重
  • java中list的用法 list集合的常用操作方法汇总