楼层: 首页/ 软件技术/ C 语言/ 工具链实战:Makefile、gdb、valgrind
工

工具链实战:Makefile、gdb、valgrind

Makefile · gdb · valgrind

单个文件敲一行 gcc 还行,可项目一旦拆成十个 .c 文件,每次手敲又长又容易漏。这一章给三件"真正上班用得到"的工具:一键编译、单步调试、内存体检。

Makefile:一条命令编译整个项目

Makefile 是个"配方表":写清楚"依赖关系 + 怎么造",以后敲 make 就自动只重编改动过的文件。下面是最小可用版。

Makefile(注意命令行前是一个 Tab,不是空格)

CC = gcc CFLAGS = -Wall -g -std=c11 # 编译参数 TARGET = app OBJS = main.o student.o list.o # 默认目标:造 app $(TARGET): $(OBJS) $(CC) $(CFLAGS) -o $(TARGET) $(OBJS) # 每个 .o 依赖它对应的 .c %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ clean: # make clean 删掉生成产物 rm -f $(OBJS) $(TARGET)

用法

$ make # 自动编译,只重编改过的文件 $ ./app $ make clean # 打扫战场

gdb:让程序单步走给你看

程序崩了但不知道死哪一行?用 gdb。前提是编译时加了 -g。常用就四个动作。

gdb 命令干什么
gdb ./app加载程序开始调试。
b 行号 / b 函数名下断点(break)。
run跑起来,直到撞上断点。
n / s下一步(step over / step into 进函数)。
p 变量打印某个变量当前的值。
bt看调用栈:现在怎么一步步跑到这的(backtrace)。
quit退出 gdb。

valgrind:内存体检

怀疑内存泄漏或越界,但肉眼看不出来?把程序丢给 valgrind,它会模拟跑一遍,告诉你哪一行 malloc 了没 free、哪一行读越界了。

用法与典型输出

$ valgrind ./app ==1234== Invalid write of size 4 ==1234== at 0x109XXX: main (main.c:12) # 第 12 行写越界了 ==1234== ==1234== 4 bytes in 1 blocks are definitely lost in loss record 1 ==1234== at malloc (vg_replace_malloc.c:...) ==1234== by main (main.c:8) # 第 8 行 malloc 的没 free

记怎么看 valgrind 报告

别被一堆等号线吓住。只找两类关键词:Invalid read/write(越界读写)和 definitely lost(铁定泄漏)。by main (xxx.c:行号) 那行就是罪魁祸首,回去改那一行就行。

学习资源(都能白嫖)

资源特点适合阶段
cppreference(C 部分)标准库函数权威参考,每个函数都有例子。查 API,随手翻
K&R《C 程序设计语言》C 之父亲笔,薄而经典,半小时一篇。学完基础后精读
Learn-C.org交互式在线练习,浏览器里直接编译运行。零基础边学边敲
Compiler Explorer(godbolt)写 C 代码实时看它变成什么汇编,理解底层神器。学完指针后进阶