为什么我得到一个seg错误(多维数组C)

时间:2012-02-01 20:12:07

标签: c arrays multidimensional-array segmentation-fault

我似乎无法弄清楚我做错了什么。

int main(int argc, char **argv) {
  int height = 4, width = 6;
  int **map;
  map = (int **)(malloc(height * sizeof(int*)));
  for(i = 0; i < height; i++) {
    map[i] = (int *)(malloc(width * sizeof(int)));
  }
  fill_map(&map, height, width);
}

void fill_map(int ***map, int height, int width) {
  int i, k, character;
  for(i = 0; i < height; i++) {
    k = 0;
    while((character = getchar()) != '\n') {
        *map[i][k] = character;
        k++;
    }
  }
}

我在fill_map中得到段错误,在内部while循环中,为什​​么?

6 个答案:

答案 0 :(得分:3)

不要发送&amp; map到函数,更改原型接收(int ** map)或使用(* map)[i] [k]。这是因为间接运算符*的优先级低于[]运算符。

答案 1 :(得分:1)

你期望如何结束你的while循环,你有没有保持“\ n”你的阵列?你刚刚分配了内存并试图通过它。它永远不会找到“\ n”,因此while循环离开了内存位置,你就会得到分段错误。

答案 2 :(得分:0)

我会使用gdb或其他调试器。使用调试符号编译程序,在那里运行它,它会告诉你你在哪里进行segfaulting。

答案 3 :(得分:0)

首先 - 'prmg'和'perreal'给出的建议。

不要强制转换malloc的返回值。 malloc返回一个void *,而且演员是不必要的。如果你忘了#include <stdlib.h>,你就是在为自己找麻烦。

map = malloc( height * sizeof *map );

答案 4 :(得分:0)

您的细分错误来自于您错误地取消引用map这一事实;您应该将其写为(*map)[i][k]而不是*map[i][k]。虽然最好不要在调用&时忽略fill_map并相应地调整原型:

fill_map(map, height, width);
...
void fill_map(int **map, int height, int width)
{
  ...
  map[i][k] = character;
  ...
}

您可以像这样清除malloc来电:

map = malloc(height * sizeof *map);

map[i] = malloc(width * sizeof *map[i]);

C 1 中没有必要使用演员表,这被认为是不好的做法。

<小时/> 1 这在C ++中是 not true;需要强制转换,但如果您正在编写C ++,那么您应该使用new而不是malloc

答案 5 :(得分:0)

您使用的不是2D阵列,只是模拟它。在现代C中,从C99开始,使用“可变修改类型”,您的任务就像这样简单:

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

void fill_map(size_t height, size_t width, char map[height][width]) {
  int character;
  for(size_t i = 0; i < height; i++) {
    for (size_t k = 0; k < width; k++) {
      if ((character = getchar()) != '\n')
        map[i][k] = character;
      else break;
    }
  }
}

int main(int argc, char **argv) {
  size_t height = 4, width = 6;
  char (*map)[width] = malloc(sizeof(char[height][width]));
  fill_map(height, width, map);
}
  • 首先传递矩阵尺寸,然后您可以在矩阵参数
  • 的声明中使用它们
  • 使用size_t进行索引
  • 不要强制转换malloc
  • 小心你的循环界限
  • 还可以更好地检查文件结尾(作业)