这个c函数如何减少我的计数器?

时间:2013-08-09 22:26:32

标签: c gcc compiler-construction call

我有以下代码:

int i;
for(i=0;i<2;i++) {
  ...
  printf("i = %d\n",i);
  rtdb_pull(rtdb, buf, &ncenter);
  printf("i = %d\n",i);
  ...
}

当我运行它时,它会很好地通过i = 0,但是一旦i = 1,rtdb_pull函数似乎会减少计数器,所以我最终陷入循环。这怎么可能?我没有将i传递给rtdb_pull,rtdb_pull也没有使用名为i的变量。

如果我这样做,一切正常:

int i;
for(i=0;i<2;i++) {
  ...
  printf("i = %d\n",i);
  int j = i;
  rtdb_pull(rtdb, buf, &ncenter);
  i = j;
  printf("i = %d\n",i);
  ...
}

为了记录,我在Ubuntu 13.04上使用gcc 4.7.3并使用ANSI c进行编译。我没有收到编译器的任何相关警告。

4 个答案:

答案 0 :(得分:1)

很明显rtdb_pull()导致了这种情况,因为否则编译器会被破坏。

正在发生的事情是rtdb_pull()正在覆盖此函数中的编程错误导致的i。巧妙地i会被0覆盖。根据内存中最终的内容,您的恶意函数可能会覆盖其他变量,或者根本不会覆盖。

您的错误代码似乎不会覆盖j,这只是另一种巧合。

如果发生这种情况,只有在您提供rtdb_pull()代码以及定义和分配rtdbbufncenter的代码时才能获得答案。< / p>

更改代码,比如在编写时动态分配ncenter,可能会使此问题消失。但它无法解决根本原因。所以要非常小心,它可能会再咬一口!

答案 1 :(得分:0)

如果你的rtdb_pull()是一个非托管程序集体的函数,它忘记了push-pop备份,那么你的循环计数器(在寄存器而不是内存中更好)可能被rtdb_的汇编代码破坏了。

如果程序集的寄存器备份是自动完成的,那么错误在程序集体之外(rtdb_pull()可能是一个简单的C函数?那么错误必须是未定义的行为内存访问)

答案 2 :(得分:0)

首先,您发布了一个代码段,因此可能会有其他原因或考虑原因发生这种情况!,但参数rtdb看起来很像rtdb函数的地址?

   rtdb_pull(rtdb, buf, &ncenter);

这是真的,如果是的话,rtdb是否可以访问i?

答案 3 :(得分:0)

由于rtdb_pull(rtdb, buf, &ncenter)似乎将其结果写入buf,可能还有ncenter,因此我想了解这些内容是如何分配的。例如,如果buf是本地的,并且分配的字节太少,则该函数可能会溢出缓冲区,导致堆栈中的其他变量,包括i。让我们看看那些声明和相关作业。