c - 为什么 GCC 会在教科书练习中没有 clang 的地方出现错误?

标签 c gcc clang

使用 Adam Hoover 的“使用 C 和 Unix 进行系统编程”学习 C。我遇到了第4章的问题,这让我很困惑。问题如下:

In the following code, the first printf() reached produces the output "14," but the second printf() can cause a bus error or a segmentation fault. Why?

书中原代码:

main()
{ 
  int *p;
  funct(p);
  printf("%d\n",*p);
}
funct(int *p2)
{
  p2=(int *)malloc(4);
  *p2=14;
  printf("%d\n",*p2);
}

我稍微修改过的“调试”(printf all the things)版本:

#include <stdio.h>
#include <stdlib.h>

void funct(int *p2);

int main(){
    int *p;
    printf("main p - address: %p\n", p);

    funct(p);
    printf("main p - address: %p\n", p);
    printf("main p value: %d\n", *p);
}  

void funct(int *p2){
    printf("funct (pre malloc) p2 - address: %p\n", p2);

    p2 = (int *)malloc(4);
    printf("funct (post malloc) p2 - address: %p\n", p2);

    *p2 = 14;
    printf("funct p2 value: %d\n", *p2);
}  

我已经使用 gcc 和 clang(在 ubuntu linux 上)编译了这个示例,并且 clang 不会为应该这样做的代码产生段错误。我对此感到困惑有一段时间了,无法想象这是为什么或如何。欢迎任何见解。

谢谢。

最佳答案

int *p;
funct(p);
printf("%d\n",*p);

这是错误的。 p 按值传递。因此,函数中的任何修改都不会影响 main 中的 p。取消引用未初始化的指针行为是未定义的。

你真正需要做的是——

funct(&p) ; // in main

void funct( int **p ){
   *p = malloc(sizeof(int));
   // ...
}

关于c - 为什么 GCC 会在教科书练习中没有 clang 的地方出现错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7466934/

相关文章:

java - 将输入字符串转换为十六进制数表示

c++ - 是否允许编译器优化堆内存分配?

optimization - LLVM opt mem2reg无效

git - 在一系列 git 提交上运行 git-clang-format

c - 组装,画图

c++ - Eclipse/Code::Block 不运行应用程序

c - 在 C 中声明字符串的区别

我们可以在 c 中的 execvp() 中将变量作为命令行参数传递吗

c - 当数组大小固定时,sscanf 无法正确转换 float

c++ - C(++) 结构力额外填充