【问题标题】:error: conflicting types for (a function that returns a pointer)错误:(返回指针的函数)的类型冲突
【发布时间】:2020-07-27 14:40:16
【问题描述】:

我已经定义了一个结构和一个返回指向该结构的指针的函数,每当我尝试调用它时,我都会收到运行时错误:** error: conflicting types for ‘readVirus’**

typedef struct virus {
unsigned short SigSize;
char virusName[16];
unsigned char* sig;
}virus;

virus* readVirus(FILE* file){
virus *res;
res=(virus*)malloc(sizeof(virus));
fread(&res->SigSize,2,1,file);
fread(&res->virusName,16,1,file);
res->sig=(char*)malloc(res->SigSize);
fread(res->sig,res->SigSize,1,file);
return res; 
free(res);
}


int main(int argc, char **argv) {
FILE *input;
input = fopen(argv[1],"rb");
virus *res;
res=(virus*)malloc(sizeof(virus));
res=readVirus(input);
printf("%s",res->virusName);
free(res);
fclose(input);
}

我尝试将 readVirus 的主体直接复制到 main 并删除该函数并且它运行良好,所以我认为它不是函数实现问题。 在此先感谢:)

【问题讨论】:

  • 完整的错误信息是什么?它应该告诉您冲突的类型实际上是什么。
  • 另外,res=(virus*)malloc(sizeof(virus)); res=readVirus(input); 是内存泄漏。
  • virusDetector.c:在顶层:virusDetector.c:31:8:错误:'readVirus' 病毒的类型冲突* readVirus(FILE* file){ ^~~~~~~~~~ virusDetector.c:26:9: 注意: 'readVirus' 的先前隐式声明在这里 res=readVirus(input); ^~~~~~~~~
  • 使用 struct virus 而不是 virus,或添加 typedef
  • ⟼请记住,尤其是在 Stack Overflow 上学习和提问时,尽可能让代码保持井井有条是很重要的。 Consistent indentation 有助于传达结构,更重要的是,有助于传达意图,这有助于我们快速找到问题的根源,而无需花费大量时间尝试解码正在发生的事情。

标签: c function file pointers types


【解决方案1】:

拥有

typedef struct virus {
unsigned short SigSize;
char virusName[16];
unsigned char* sig;}

struct virus* readVirus(FILE* file){

第一个';'在 struct 的 '}' 之后丢失并且您没有定义类型 virus,因此您需要在每个位置使用 struct virus你的代码

但可能你想要:

typedef struct virus {
  unsigned short SigSize;
  char virusName[16];
  unsigned char* sig;
} virus;

允许只编写 virus 而在其定义之后没有 struct

我鼓励您使用大写字符来开始您的类型名称,因此 Virus 而不是 virus,这有助于阅读代码以区分例如变量的名称


main

中的问题

我收到一个运行时错误说 ** error: conflicting types for ‘readVirus’**

这是您编译程序时产生的消息,而不是您执行它时产生的消息,这是因为在该行中:

res->sig=(char*)malloc(res->SigSize);

res 是一个指向 virus 的指针,但你的演员表是 (char*),类型不一样。

您可以修复 cast 以使用 (virus*) 但实际上您可以将其删除。

在做:

res=malloc(sizeof(virus));
res=readVirus(input);

第一个赋值丢失,引入内存泄漏,删除第一个赋值

注意在 main 中你也不要释放 res,在程序结束时这不是问题,除非你想用valgrind

之类的工具

你使用 argv[1] 在程序收到参数之前没有检查,我鼓励你在程序开始时做类似的事情:

int main(int argc, char **argv) {
  if (argc != 2) {
    fprintf(stderr, "Usage: %s <file>\n", *argv);
    return -1;
  }
  else {

我鼓励您检查 fopen 的结果,以检查您是否能够打开文件并在无法打开文件时发出信号。如果你有函数 strerror 使用它,例如:

 if (input == NULL) {
   fprintf(stderr, "cannot open %s : ", argv[1], strerror(errno));
   return -1;
 }

用最后一个换行符刷新你的打印,你只想打印一个字符串,所以在 main 替换

printf("%s",res->virusName);

通过

puts(res->virusName);

问题 readVirus

fread(&res->SigSize,2,1,file);
fread(&res->virusName,16,1,file);

不要使用文字数字来表示尺寸,无论发生什么都使用 sizeof 来获得正确的尺寸:

fread(&res->SigSize, sizeof(res->SigSize), 1, file);
fread(&res->virusName, sizeof(res->virusNamee), 1, file);

我还建议您检查读取是否成功并在出现错误时发出信号

您确定该文件是二进制文件,其中 sigSize 是二进制表示吗?我的意思是对于大小 1234,文件包含代码 4 的字节,然后是代码 210 的字节,或者相反

【讨论】:

  • 感谢您的回答。实际上我确实定义了,我只是忘了在这里输入它:) 我要编辑它。无论如何,我认为这不是问题。
  • @AmroAnabtawi 是的,请注意,您很容易看到不像您那样将所有内容放在一个块中,缩进并且只有“} 病毒;”最后一行的可读性更高
  • @AmroAnabtawi 我编辑了我的答案以添加更多评论
猜你喜欢
  • 1970-01-01
  • 2015-10-13
  • 1970-01-01
  • 2015-04-05
  • 2021-10-23
  • 1970-01-01
  • 2014-01-04
  • 1970-01-01
相关资源
最近更新 更多