奇怪:printf()影响变量值

时间:2013-04-29 22:54:53

标签: c linux

这是一段代码:

int somefunc() {
    /* ... */
    while ((pos = KMP_index(array, size, pattern, plen)) > -1) {
        count++;
    }
    return count;
}
在多个子进程中调用

somefunc(),每个fork一次调用。

我的代码在Linux x86_64和i386上编译并按预期工作。但是当我在Atom上网本(Arch Linux i686)上运行时,count变量永远不会超过2!

while (...) {
    count++;  //succesfully increments 
}
return count; //it's maximum 2!

但是,如果我添加printf():

while (...) {
    count++;  //succesfully increments
    printf("%d", anything);
}
return count; //value as expected

打印空字符或fflush stdout在此处不起作用。我必须打印至少一个字符,然后才变量很好。它让我疯了。

有人可以告诉我,为什么我甚至不得不使用这种“解决方法”? 这可能是我的linux环境的问题吗? (没什么特别的,GCC 4.8,库存内核) 谢谢。

P.S整个来源都在这里http://pastebin.com/4eEHMbKn。 是的,这是一个功课:)我需要创建一个类似grep的实用程序,在单独的进程中处理每个文件。

1 个答案:

答案 0 :(得分:5)

您的KMP_index()来电KMP_failure()来初始化failure[]数组。不幸的是,KMP_failure()无法初始化数组的第一个元素。

KMP_index()会检查failure[]的第一个元素。由于该值未设置,因此KMP_index()的结果是半随机的,具体取决于先前函数调用堆栈(局部变量)的方式。这解释了为什么该函数的结果取决于您在KMP_index()调用之前调用的内容。

(我注意到你的代码编译时没有在GCC 4.6.3上发出任何警告,因此编译器也没有注意到。)

最有可能的是,您的成功测试是在64位平台上进行的,其中偶然事件会使该数组的第一个元素与该32位Atom体系结构不同。特别是,printf()改变了这种情况,因为它使用了相当多的堆栈:KMP_index()的下一次调用将得到一个failure[]数组,其中剩余的垃圾中剩下的是初始元素致电printf()

事实上,使用-m32-m64进行编译以及不同的优化设置(-Os-O3)会在{{1}的第一个元素中生成不同的半随机值}}

希望这有帮助。