最终审判
既然修改了代码,再用valgrind
运行一次:
泄漏已修复
你运行了和刚刚一样的测试数据,但这次程序清理了堆上的所有东西。
你破案了吗?即使这次没能发现泄漏并修复它也不用担心,存储器泄漏是C程序中最难发现的错误。事实上,现在你用的很多C程序都隐藏着一些存储器错误,所以valgrind
工具就非常有用。
发现泄漏。
定位泄漏。
检验泄漏是否修复。
这里没有蠢问题
问:
valgrind
说泄漏的存储器是在第46行创建的,但我们却修改了另一行代码,为什么?答:虽然数据“Loretta…”是由第46行代码放到堆上的,但泄漏却发生在变量(
current->question
)重新赋值的那一刻,因为当时变量指向的“Loretta…”还没有释放。创建数据不会发生泄漏,只有当程序失去了所有对数据的引用才会导致泄漏。问:我的Mac/Windows/FreeBSD系统可以安装
valgrind
吗?答:在http://valgrind.org上可以查看valgrind最新发行版的详细信息。
问:那么
valgrind
是怎么拦截malloc()
与free()
的?答:
malloc()
和free()
包含在C标准库中,而valgrind
有一个库,里面有它自己的malloc()
与free()
。当用valgrind
运行程序时,程序会使用valgrind
的函数,而不是C标准库中的函数。问:为什么编译器在编译代码时不默认包含调试信息?
答:因为调试信息会使可执行文件变大,同时也可能让程序变得更慢。
问:
valgrind
这个名字的由来是什么?答:valgrind是英灵殿1入口的名字,而valgrind(程序)为你打开了一扇通向计算机堆的大门。
1 北欧神话中,死亡之神奥丁用来款待阵亡将士英灵的殿堂。——译者注
要点
valgrind
可以检查存储器泄漏。
valgrind
通过拦截对malloc()
与free()
的调用来工作。程序在停止运行时,
valgrind
会打印留在堆上数据的详细信息。编译代码时,如果在可执行文件中加上调试信息,
valgrind
可以提供更多信息。多次运行程序可以缩小泄漏的范围。
valgrind
可以告诉你源文件的哪行代码把数据放到了堆上。
valgrind
可以用来检验泄漏是否已修复。