【发布时间】:2017-02-06 19:33:49
【问题描述】:
我声明了一个用 C 实现的链表如下:
struct node_List {
int i;
char * name;
struct node_List* next;
};
typedef struct node_List nodeList;
然后我将列表头全局声明为:
nodeList list; // head of the list - does not contain relevant data
最后,我有一个函数id(char * s),它的唯一参数是字符串s。
nodeType id(char *s)
{
nodeType *p; // another List type
if ((p = malloc(sizeof(nodeType))) == NULL) {
// error: out of memory;
}
nodeList * node = &list;
// printf(" ");
while (node->next != NULL){
node = node->next;
if (strcmp(node->name, s) == 0){
// printf(" ");
// assign node to an attribute in p
return p;
}
}
// error: not found;
}
问题是,当我运行这个程序并调用foo("somestring") 时,程序执行error: not found 部分并中止执行,尽管字符串somestring 在列表中。
我尝试通过插入一些printf() 来执行相同的程序以进行调试,它运行良好,除了它会在输出中打印额外的字符。
每次我添加一些打印行时都会发生这种情况,例如如果我取消注释我在上面的示例中编写的两个printf()s(其中一个或两个,我得到相同的成功结果)。如果 printf 被调用时不带参数或使用空字符串 "",则它不起作用。
我不知道发生了什么,我仔细检查了列表创建和填充功能,我完全确定它们可以正常工作。我尝试更改 while 中断条件,但这也不起作用。我在 Linux(使用 gcc)和 Windows(使用 CodeBlocks 编辑器的集成编译器)上都观察到了类似的行为
printf 指令怎么会对程序产生如此大的影响?
编辑:此代码是用 Yacc 编写的语法分析器的一部分。整个代码可以在下面找到。读了很久,还没有完成,但是上面的代码已经过测试并且可以按照说明工作。
【问题讨论】:
-
您似乎跳过了列表的第一个元素。在您使用的第一步中: node = node->next;
-
该行为可能还取决于您将
list初始化为什么,以及您如何构造链表的其余部分。你没有表现出来 -
我们无法调试部分代码。请提供minimal reproducible example。
-
只是澄清一下-您是说:使用发布的代码找不到字符串,但是如果未注释两个printf,则找到字符串?
-
您很可能遇到了内存损坏问题。或者严重误入歧途的事情。使用带有Valgrind 的机器并运行它。听起来,您已经完成了足够多的工作,知道这很奇怪,并且您当前尝试调试它的方式不起作用。因此,您需要进入不同的调试模式。使代码可测试;单独测试它。确保使用 Valgrind 隔离它是干净的。然后考虑将其重新插入到更复杂的场景中。未定义的行为包括“大部分情况下似乎可以工作”的选项。
标签: c list pointers printf yacc