【问题标题】:Initializing a big array of a certain structure -- getting seg faults初始化某个结构的大数组——得到段错误
【发布时间】:2015-03-19 20:19:41
【问题描述】:

下面的代码给了我一个段错误。 gdb 说它来自memos[j][k] -> cost = -1; 行,但我不知道到底出了什么问题。我在猜测我是如何分配内存的,并且数组索引错误地超出了界限?

memo_array_t mk_empty_memo_array(int l) {

    int n = pow(2, l+2);
    memo_t **memos = (memo_t **) malloc(n*sizeof(struct memo_s));
    for(int i = 0; i < pow(2, l+2); i++) {
        memos[i] = (memo_t *) malloc(n*sizeof(struct memo_s *));
    }
    for (int j = 0; j < n; j++) {
        for (int k = 0; k < pow(2, l+2); k++) {
            memos[j][k] -> cost = -1;
            memos[j][k] -> color = -1;
            memos[j][k] -> split = -1;
            memos[j][k] -> box = NULL; 
            memos[j][k] -> split_value = -1; 
        }
    }

    memo_array_t memo_array = (memo_array_t) malloc(sizeof(struct memo_array_s));
    memo_array -> dim = n;
    memo_array -> memos = memos;

    return memo_array;
}

如果你想查看结构类型定义:

typedef struct memo_s {
  int cost;
  int color;
  int split;
  double split_value;
  box_t box;  
} *memo_t;

typedef struct memo_array_s {
  int dim;
  memo_t **memos;
} *memo_array_t;

【问题讨论】:

  • 首先,don't cast the result of malloc in C。然后,您在两个调用中混合了 sizeof 运算符的类型。第一个调用分配一个 pointers 数组,第二个调用分配一个 values 数组。或者更确切地说,第一次调用应该使用指向结构的双指针,或指向memo_t 的指针作为sizeof 运算符的操作数。

标签: c memoization


【解决方案1】:

应该是:

memo_t **memos = malloc(n*sizeof(struct memo_s **));
for(int i = 0; i < n; i++) {                // ^^ two *s here!
    memos[i] = malloc(n*sizeof(struct memo_s *));   

    // And finally, allocate the actual structs:  
    for(int j = 0; j < n; j++) {    
        memos[i][j] = malloc(sizeof(struct memo_s); 
    }
} 

所以第一个malloc 分配了一个指针数组,第二个malloc 分配了一个指针数组,第三个malloc(你错过了)为实际的结构分配空间(因为你有pointers 的 2D 数组,而不是 structs 的 2D 数组)。

另外,don't cast the result of malloc。并且在循环条件中,使用你计算的n的值,而不是再次计算。

我认为只有一个结构名称然后在名称后添加* 使其成为指针会更简单,而不是将memo_s 作为实际结构并将memo_t 作为指针到那个结构。我在尝试解决这个问题时发现它真的很混乱。

【讨论】:

  • 好的,我做了建议的更改。不幸的是,我仍然收到相同的错误(备忘录 [x][y] -> cost = -1 处的段错误)。我也解决了投射问题。
  • 等一下,我还没有解决你所有的错误...我会尽快编辑答案。同时检查 Joachim 的答案。
【解决方案2】:

除了您对数组的分配(部分)错误之外,问题在于您没有分配实际的结构。 memo[j][k] 是一个指针,但你不会让它指向任何地方,所以当你取消引用它时,你有 undefined behavior

【讨论】:

  • 我想我对你的建议感到困惑——我的代码中的第一个 for 循环似乎正在为 memo[j][k] 分配空间
  • @Craig 你在某种程度上拥有一个指针数组。您分配外部和内部数组,但不分配包含的指针。请参阅 Zenith 的答案。
猜你喜欢
  • 1970-01-01
  • 2020-07-30
  • 2021-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-21
  • 2015-07-29
相关资源
最近更新 更多