为什么海湾合作委员会在教科书演习中没有瑕疵?

jer*_*emy 1 c gcc clang

使用Adam Hoover的"使用C和Unix进行系统编程"学习C. 我从第4章遇到的问题让我很困惑.问题如下:

在下面的代码中,第一个printf()到达产生输出"14",但第二个printf()可能导致总线错误或分段错误.为什么?

书中的原始代码:

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

我稍加修改的"调试"(printf所有的东西)版本:

#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);
}  
Run Code Online (Sandbox Code Playgroud)

我已经使用gcc和clang(在ubuntu linux上)编译了这个示例,并且clang不会为应该执行此操作的代码生成seg错误.我现在已经困惑了一段时间,无法想象为什么或如何做到这一点.欢迎任何见解.

谢谢.

Mah*_*esh 7

int *p;
funct(p);
printf("%d\n",*p);
Run Code Online (Sandbox Code Playgroud)

这是错的.p按值传递的.所以在功能上做过任何修改都不会影响pmain.并且取消引用未初始化的指针行为是未定义的.

你真正需要做的是 -

funct(&p) ; // in main

void funct( int **p ){
   *p = malloc(sizeof(int));
   // ...
}
Run Code Online (Sandbox Code Playgroud)