首页 > 解决方案 > 初始化数组时 C 中的分段错误

问题描述

我正在尝试在一个单独的函数中动态创建一个数组并将一些变量存储在该数组中,我遇到了以下问题:我写的时候是怎么回事?

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

void foo(int **arr, int N) {
  *arr = malloc(sizeof(int));

  for (int index = 0; index <= 4; index++) {
    *arr[index] = 1;
  }
}

int main() {
  int *arr; 
  foo(&arr, 5);

  for (int bar = 0; bar <= 4; bar++) {
    printf("%d ", arr[bar]);
  }
}

我得到这个输出;

exited, segmentation fault

但是,当我运行以下命令时;

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

void foo(int **arr, int N) {
  *arr = malloc(sizeof(int));
}

int main() {
  int *arr; 
  foo(&arr, 5);

  for (int index = 0; index <= 4; index++) {
    arr[index] = 1;
  }

  for (int bar = 0; bar <= 4; bar++) {
    printf("%d ", arr[bar]);
  }
}

我得到这个输出;

1 1 1 1 1

我一直在试图弄清楚如何修复第一块代码以使其正常工作,但我似乎不知道该怎么做。任何帮助将不胜感激,至少了解为什么会发生分段错误。

标签: carrayssegmentation-fault

解决方案


这里有几件事是重要的细节。

Evgeny 是正确的,您需要分配 N 个 sizeof int 的东西。否则你的程序是错误的,并且会写入无效的内存位置。

段违规的原因需要几分钟才能找到。我在整个代码中添加了 printf 语句,以便能够查看发生段违规的位置。它表明将 1 分配给数组元素是它发生的地方。

然后我怀疑绑定/顺序是问题,所以将括号放在 *arr 周围,以非常清楚地表明这是意图。在那之后,段违规就消失了。我还将初始化更改为索引,以便可以轻松验证分配结果。

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

void foo(int **arr, int N) 
{
    *arr =(int *) malloc(sizeof(int) * N);

    for (int index = 0; index < N; index++)
    {
        printf("before assignment\n");
        (*arr)[index] = index;
        printf("after assignment\n");
    }
}

int main() 
{
  int *arr; 
  foo(&arr, 5);

  for (int bar = 0; bar < 5; bar++) 
  {
    printf("%d ", arr[bar]);
  }
}

简而言之,一种有用的快速而肮脏的技术是插入一堆 printfs 来帮助缩小问题发生的范围。


推荐阅读