传递struct指针会导致整数溢出,看似没有理由

时间:2014-03-11 02:16:11

标签: c

注意:我在写这个问题的过程中自己解决了这个问题。令人惊讶的是,只写出问题,包括细节,通常可以帮助人们解决自己的问题。更不用说阅读-Wall的输出了很多。

尽管如此,我仍然会发布此信息,以便将来遇到此问题的人可以自行解决。

如果你认为我应该社区维基,请告诉我。


最初的问题:

出于某种原因,当我通过两个函数传递一个struct指针时,它似乎会扭曲内部的数据。

我的机智就此结束了。也许对于像我这样的C noob来说这是一个雄心勃勃的项目,但是,我似乎无法弄清楚为什么会这样。

以下是一些相关的代码段:

来自data.h的

typedef struct data{
  unsigned int dollar_bank : 32;
  unsigned int dollar_bank_extra : 32;
  // 13 more ints
} data;

void file_save(data *d, char *file);

data.c:

void file_save(data *d, char *file){
  FILE *f = fopen(file,"w");
  fprintf(f,
    "%05i,%05i,[...]%05i",
    d->dollar_bank,
    d->dollar_bank_extra,
    // etc
  );
  fclose(f);
}

main.c中:

render(&d);
prompt(&d);
data_save(&d,"data"); // Saves correctly

interface.c:

static void exec_command(data *d, char *cmd, int *exit_code){
  // Here I have this debug line,
  printf("%i\n",d->dollar_bank); 
  // supposed to print 1000 (as it does in main())
  // but prints a random number like -1246981692364 instead
  // if I invoke file_save() here, it writes garbage into the file.  Not very useful.
}
void prompt(data *d){
  char cmd[5];
  int exit_code = 0;
  while(1){
    // ...
    exec_command(&d, cmd, &exit_code);
    if(exit_code)    break;
  }
}

我非常感谢可能给予的任何帮助。我觉得我错过了一些非常明显的东西。如果您需要更多代码段,请询问。

编译器= GCC 4.7.3

编译器输出:

interface.c: In function ‘exec_command’:
interface.c:102:5: warning: passing argument 1 of ‘file_save’ from incompatible pointer type [enabled by default]
In file included from interface.c:3:0:
data.h:22:6: note: expected ‘struct data *’ but argument is of type ‘struct data **’
interface.c: In function ‘prompt’:
interface.c:123:5: warning: passing argument 1 of ‘exec_command’ from incompatible  pointer type [enabled by default]
interface.c:93:6: note: expected ‘struct data *’ but argument is of type ‘struct data **’
interface.c:121:10: warning: ignoring return value of ‘fgets’, declared with attribute warn_unused_result [-Wunused-result]

我很确定我错过了一些非常明显的东西。

1 个答案:

答案 0 :(得分:1)

当我复制GCC的输出时(当然是-Wall),我找到了解决方案。

interface.c:123:5: warning: passing argument 1 of ‘exec_command’ from incompatible  pointer type [enabled by default]
interface.c:93:6: note: expected ‘struct data *’ but argument is of type ‘struct data **’

我想到了,并意识到我 错过了一些非常明显的东西:将&d(原始结构的地址)传递给另一个函数,将指向一个地址地址。据我所知,它甚至不是有效的指针,但仍然被解释为struct data **。这意味着通过保存功能,我传递了struct data ***

解决方案就像改变一样简单:

exec_command(&d,[...]);

exec_command(d,[...]);

所以现在不打印-12345474293845,而是打印1000。万岁!


同样,如果你认为我应该将这个问题/答案归功于wiki,请告诉我。然后人们可以将他们的知识添加到指针指针的主题上。

或者,如果您认为我应该删除此问题/答案,请告诉我。我不想踩到任何人的脚趾。