推敲证据

推敲证据 - 图1

好了,既然你已经用valgrind收集了不少证据,下面就来分析这些证据,看看能否得出什么结论。

  • 定位

运行了两次代码,第一次没有任何问题。只有当输入一个新嫌疑犯的名字时,存储器才会泄漏。这条线索十分重要,因为它说明泄漏不可能发生在第一次运行的代码中。回过去看源代码,问题应该发生在以下代码中:

  1. } else if (current->no) {
  2. current = current->no;
  3. } else {
  4.  
  5. /* Make the yes-node the new suspect name */
  6. printf("Who's the suspect? ");
  7. fgets(suspect, 20, stdin);
  8. node *yes_node = create(suspect);
  9. current->yes = yes_node;
  10.  
  11. /* Make the no-node a copy of this question */
  12. node *no_node = create(current->question);
  13. current->no = no_node;
  14.  
  15. /* Then replace this question with the new question */
  16. printf("Give me a question that is TRUE for %s but not for %s? ", suspect, current->question);
  17. fgets(question, 80, stdin);
  18. current->question = strdup(question);
  19.  
  20. break;
  21. }
  • valgrind提供的线索

当用valgrind运行代码并添加一名嫌疑犯时,程序分配了11次存储器,但只释放了10次,这说明什么?

valgrind告诉你程序结束时有19个字节的数据留在了堆上。看一下源代码,哪条数据像是有19字节?

最后,下面这段valgrind的输出告诉你什么?

推敲证据 - 图2

 

推敲证据 - 图3

 

推敲证据 - 图4