所以我有一个C程序。由于复杂性问题,我认为我无法发布任何代码片段。但我会概述我的错误,因为它很奇怪,看看是否有人可以提供任何见解。
我将指针设置为 NULL
。如果,在我将指针设置为 NULL
的同一函数中,我printf()
指针(使用 "%p"
),我得到 0x0
,当我在程序结束时打印一百万英里外的同一指针时,我得到 0x0
。如果我删除 printf()
并且绝对没有其他更改,然后当稍后打印指针时,我得到 0x1
,并且我的结构中的其他随机变量也有不正确的值。我正在 -O2
上使用 GCC 编译它,但如果我取消优化,它会有相同的行为,所以这不是问题。
这听起来像 Heisenbug ,我不知道为什么会发生这种情况,也不知道如何解决。有没有曾经处理过类似问题的人对如何解决此类问题有建议?我知道这听起来有点含糊。
编辑:不知何故,它现在可以工作了。谢谢大家的建议。
调试器告诉我有趣的事情 - 我的变量正在被优化。所以我重写了该函数,因此它不需要中间变量,现在它可以在有或没有 printf()
的情况下工作。 。我对可能发生的事情有一个模糊的想法,但我需要 sleep ,而不是知道发生了什么。
最佳答案
你使用多线程吗?我经常发现打印某些内容的行为足以有效地抑制竞争条件(即不会消除错误,只是使其更难以发现)。
至于如何诊断/修复它......你可以将第二个打印移得越来越早,直到你看到它的变化吗?
当您没有 printf
时,您是否总是会看到 0x1?
避免 printf
延迟/同步的一种方法是将指针值复制到第一个 printf
位置的另一个变量中,然后打印出该值稍后 - 这样您就可以看到当时的值是什么,但时间要求不那么严格。当然,当你发生奇怪的值“腐败”时,这可能不像听起来那么可靠......
编辑:您总是看到 0x1 的事实令人鼓舞。它应该更容易追踪。诚然,非多线程确实会让解释起来稍微困难一些。
我想知道这是否与额外的 printf
调用有关,从而影响了堆栈的大小。如果您在与第一个 printf 调用相同的位置打印不同变量的值,会发生什么?
编辑:好的,让我们进一步了解堆栈的想法。您能否创建另一个具有与 printf 相同类型的签名并具有足够代码以避免内联但实际上不打印任何内容的函数?调用它而不是 printf,看看会发生什么。我怀疑你还是会没事的。
基本上我怀疑你在某个地方搞砸了你的堆栈内存,例如通过在堆栈上写入数组的末尾;通过调用函数来改变堆栈的使用方式可能会掩盖它。
关于c - C 中的奇怪错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1315498/