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

C语言入门:常见陷阱与调试技巧——避坑指南

十大常见陷阱

1. 数组越界

int arr[5] = {1, 2, 3, 4, 5}; arr[5] = 10; // 越界!不报错,可能改坏别的数据

C 语言不检查数组越界。后果:改坏相邻变量、段错误、"看起来正常"但埋隐患。

防御:循环条件用< 长度,不用<=

2. 忘记 \0

char name[5]; strcpy(name, "hello"); // "hello" 需要 6 字节(含 \0),溢出!

防御:声明字符数组时多留 1 字节给\0。用strncpy限制长度。

3. 野指针(悬垂指针)

int *p = malloc(sizeof(int)); free(p); *p = 10; // 未定义行为!p 已经是野指针

防御:free(p)后立刻p = NULL

4. 内存泄漏

void leak() { int *p = malloc(1000); return; // 忘记 free(p),内存泄漏 }

mallocfree必须配对。长期运行的程序泄漏会慢慢吃光内存。

检测工具:Valgrind(Linux)、dr.memory(Windows)。

5. = 和 == 搞混

if (a = 5) // 永远为真!赋值 if (a == 5) // 比较

C 语言最常见的逻辑 bug 来源之一。

6. switch 没 break

switch (x) { case 1: printf("one"); // 没 break,穿透 case 2: printf("two"); // 也会执行 }

防御:每个 case 末尾加break

7. 整数除法截断

float result = 1 / 3; // result = 0.0(整数除法) float result = 1.0 / 3; // result = 0.333...(浮点除法)

防御:要小数结果,至少一个操作数用浮点类型。

8. scanf 忘记 &

int x; scanf("%d", x); // 错!应该是 &x scanf("%d", &x); // 对

字符串不需要&(数组名本身就是地址):

char name[50]; scanf("%s", name); // 正确

9. sizeof 误解

int arr[5]; printf("%zu", sizeof(arr)); // 20(整个数组) ​ void func(int arr[]) { printf("%zu", sizeof(arr)); // 8(指针,不是数组!) }

数组传函数后退化为指针,sizeof失效。

10. 未初始化变量

int x; printf("%d\n", x); // 垃圾值,未定义行为

防御:声明时赋初值:int x = 0;


调试技巧

printf 调试法

最简单直接,在关键位置打印变量值:

printf("DEBUG: x = %d, p = %p\n", x, (void*)p);

GDB 调试器

gcc -g program.c -o program # 编译时加 -g 保留调试信息 gdb ./program # 启动 GDB (gdb) run # 运行 (gdb) backtrace # 崩溃后查看调用栈 (gdb) print x # 查看变量值 (gdb) break main # 在 main 设断点 (gdb) next # 单步执行

Valgrind 内存检测

valgrind ./program

检测:内存泄漏、越界访问、使用未初始化内存、double free。


常见错误信息对照

错误信息原因
Segmentation fault解引用无效指针、数组越界
Bus error内存对齐问题
Double free对同一指针 free 两次
Use after freefree 后继续使用指针
Stack overflow递归无基线条件、栈上数组太大

防御性编程习惯

  1. 声明变量时赋初值— 避免垃圾值

  2. malloc 后立刻检查 NULL— 避免空指针

  3. free 后立刻置 NULL— 避免野指针

  4. 字符串操作用安全版本strncpysnprintf

  5. 循环条件用<不用<=— 避免 off-by-one

  6. 不确定优先级就加括号— 避免运算顺序错误

  7. 函数参数传指针时标注 const— 防止意外修改

总结

  • C 的陷阱大多源于"不检查"——越界、类型、空指针都不会报错

  • 调试三件套:printf、GDB、Valgrind

  • 防御性编程比事后调试更重要——写代码时就避免陷阱

  • 遇到 Segmentation fault 先查指针和数组越界

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

相关文章:

  • Token(词元),5分钟彻底搞懂
  • 百度网盘登录故障,显示网络开小差了
  • 市面上哪款降重工具,既能降重复率,又能消除论文的 AI 写作特征?
  • 【软件测试】day02设计测试点
  • 彻底解决大模型 JSON 报错:提示词 + 硬约束 + 兜底的全链路修复方案
  • 异化与伪饰:波普尔病毒的形而上学批判与大模型时代的认知危机
  • MUMmer终极指南:5步掌握基因组比对核心技术
  • ISO新兴认证全景图:42001人工智能治理与38505数据治理赋能企业数字化
  • AWS re:Invent 2021 AI/ML技术路线图:架构师级工程实践指南
  • 实战 LangGraph 循环执行:构建带自动重试的并行任务流
  • 100VIN,0.2A,耐高压LDO,XZ6203H
  • 教你如何将yolov8训练好的文件部署在RDK上
  • 解锁无损音乐宝藏:TIDAL Downloader Next Generation 让你的音乐收藏焕然一新![特殊字符]
  • Java 面试复习草稿:HashMap 与线程池
  • 在项目中使用了Nutz框架,能说一下它相比MyBatis的优势和不足吗?你们为什么选它?
  • 从零学习Kafka:生产者分区机制
  • 面试官问:“你怎么评估一个 Agent 到底好不好用?”,我笑了:“试了几个问题,没问题就行”,面试官:“你不叫评估,叫碰运气”
  • LSTM序列分类实战:门控机制、双向设计与工程调优指南
  • 终极指南:如何用DroneSecurity深度解析DJI无人机通信协议?
  • 《HarmonyOS技术精讲-UI开发 (基于NDK构建UI)》第4篇:高效Canvas绘制——NDK中的2D渲染加速
  • 一升主机跑百亿大模型:酷睿Ultra端侧AI实战指南
  • 磁盘空间告急?这个Rust工具帮你找出所有可以删的文件
  • 分钟看懂p值和置信区间:别再被_显著_忽悠了
  • 九大网盘直链下载助手完整指南:免费高速下载终极方案
  • MPC8360E内存控制器深度解析:SDRAM时序与UPM可编程接口实战
  • Bootstrap Tooltip XSS漏洞复现:从原理到防御的深度解析
  • 临床AI落地五大生死线:从模型可信度到人机协同的实战指南
  • hcip二层综合实验
  • LinkSwift终极指南:如何优雅获取九大网盘直链下载地址
  • Ghostty + Fish + Starship + fzf + zoxide + Raycast