关于 C 中的链表的问题。假设我们有以下结构,这些结构定义了链表中的节点和一个写得不好的 free_list 函数,(在我看来)应该会导致错误:
typedef struct node *nodeT;
typedef struct node
{
int* elem;
nodeT next;
} *nodeT;
void free_list(nodeT list)
{
nodeT node;
for (node = list; node; node = node->next)
{
free(node->elem);
free(node);
}
}
正如你在上面看到的,我们已经将 node 定义为nodeT和一个释放列表free_list的函数。对我来说,明显的错误是在free_list函数里面for我们没有一个临时指针来存储节点值。
但是,当我编译代码(在 Linux 上)时,我在其中创建了一个包含少量元素的链表,程序并没有崩溃,似乎一切正常。
我的问题是:有没有一种简单的方法可以证明这个函数(free_list)写得不好?简单来说,我的意思是设置一些编译器标志(-Wall
不显示任何错误)或使用诸如Valgrind
(与 一起使用memcheck
,没有太大帮助)之类的工具?
更新:按要求测试用例:
int main()
{
nodeT myType;
nodeT tmpPtr;
myType = malloc(sizeof(nodeT));
myType->item = malloc(sizeof(int));
*(myType->item) = 0;
myType->next = malloc(sizeof(nodeT));
tmpPtr = myType->next;
tmpPtr->item = malloc(sizeof(int));
*(tmpPtr->item) = 1;
tmpPtr->next = malloc(sizeof(nodeT));
tmpPtr = tmpPtr->next;
tmpPtr->item = malloc(sizeof(int));
*(tmpPtr->item) = 2;
tmpPtr->next = malloc(sizeof(nodeT));
tmpPtr = tmpPtr->next;
tmpPtr->item = malloc(sizeof(int));
*(tmpPtr->item) = 3;
tmpPtr->next = NULL;
free_list(myType);
return 0;
}
这是Valgrind
输出:
valgrind --tool=memcheck ./a.out
...
==4318== Invalid read of size 8
==4318== at 0x400579: free_list (in /home/melon/a.out)
==4318== by 0x40069E: main (in /home/melon/a.out)
==4318== Address 0x51f1048 is 0 bytes after a block of size 8 free'd
==4318== at 0x4C2A82E: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4318== by 0x400574: free_list (in /home/melon/a.out)
==4318== by 0x40069E: main (in /home/melon/a.out)
...