fork没有分段错误

时间:2015-07-24 17:14:15

标签: c segmentation-fault fork

此代码产生分段错误:

int main(int argc, char *argv[]){
    int *n; 
    *n = atoi(argv[1]);
    printf("n: %d \n", *n);
    return 0;
}

虽然这有效:

int main(int argc, char *argv[]){
   int *n; 
   *n = atoi(argv[1]);
   pid_t pid = fork();
   if (pid == 0)
     return 0;
   else
     printf("n: %d \n", *n);
   return 0;
}

为什么第二个用叉子工作?我知道在int *n之后,我应该使用intmalloc()分配空间,但使用fork()似乎会自动执行此操作。

编辑: 现在我明白了未定义的行为:) 但现在我问:这个具体案例的原因是什么?

4 个答案:

答案 0 :(得分:7)

它不起作用。 (或者更确切地说,你有未定义的行为)

1)fork只是隐藏了segfault,因为你没有检查子进程的退出代码。

2)记忆的分配不是自动的 - 永远!

您只是写一个随机位置,您可能只是“幸运”,在第二个版本中,随机位置在您的处理空间内。

答案 1 :(得分:4)

您的代码段都会调用undefined behaviour,礼貌,

  1. 使用未初始化且无效的内存*n
  2. (可能)使用未初始化且无效的内存argv[1](如果argc不是>=2
  3. 分段错误是 UB的众多副作用之一。 UB案例也包括无缝工作场景。

      

    为什么第二个用fork工作?

    它与fork() UB的存在(或不存在)无关。 TL; DR

      

    但是使用fork()似乎会自动执行此操作。

    视觉效果可能具有欺骗性。不要把钱花在UB上。

答案 2 :(得分:3)

因为n未初始化并因此指向未知的内存地址,所以您正在调用未定义的行为。它可能会崩溃(如第一个示例中所示),或者可能不会崩溃(如第二个示例中所示)。

在这样的情况下,添加未使用的变量这样简单的事情会导致程序崩溃,而不是之前,反之亦然。

n分配内存,您将不会遇到此问题。

编辑:

当你运行第二个程序时运行./test 100,无论多少次运行,这都是运气的问题。您添加了对fork(在这种情况下)的调用的事实恰好重新排列了内存布局的方式,以便它可以工作。稍后您可能决定拨打printf进行额外的调试,突然之间它再次开始崩溃。

添加fork调用并未自动分配任何空间。

防止崩溃的唯一方法是为n分配内存,并确保argc至少为2,以便argv[1]指向某个有意义的内容。

答案 3 :(得分:0)

当你运行fork并且返回0时,你没有看到segfault,你的代码永远不会运行printf ("% d", *n)

当您尝试访问不允许的内存位置时会发生分段错误,因此解决方案是通过malloc或calloc函数分配内存,否则仍会出现问题。 试试这个:

 n=malloc(sizeof(int));
 *n=atoi(argv[1]);

问候