【问题标题】:Segmentation fault while dynamic allocation of 2D array in C在C中动态分配二维数组时出现分段错误
【发布时间】:2013-06-27 23:43:22
【问题描述】:

我是 C 编程的新手(经过很长时间重新学习)。我正在尝试使用 malloc 将内存动态分配给二维数组。我已经尝试按照thisthis 等stackoverflow 上的答案进行操作。但我仍然遇到分段错误。

我的代码如下

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

void allocate2DArray(int **subset, int a, int b)
{
  subset = (int **)malloc( a * sizeof(int *));
  int i,j;

  for(i = 0 ; i < a ; i++)
    subset[i] = (int *) malloc( b * sizeof(int));

  for(i = 0 ; i < a ; i++)
     for(j = 0 ; j < b ; j++)
        subset[i][j] = 0;
}

int main()
{
  int **subset;
  int  a = 4, b = 4;
  allocate2DArray(subset, a, b);
  int i,j;
  for( i = 0 ; i < a  ; i++)
  { 
     for( j = 0 ; j < b ; j++)
     {
        printf("%d ", subset[i][j]);
     }
     printf("\n");
  }
} 

当我注释行以打印数组时,它不会给出任何错误并且程序在没有分段错误的情况下执行。请帮助我了解我哪里出错了。

【问题讨论】:

  • C 中的函数参数按值传递。所以你在main 中的函数调用什么都不做(除了内存泄漏)。

标签: c multidimensional-array malloc


【解决方案1】:

All problems in computer science can be solved by another level of indirection:

void allocate2DArray(int ***p, int a, int b)
{
    int **subset;
    *p = (int **) malloc(a * sizeof(int *));
    subset = *p;

// ...
allocate2DArray(&subset, a, b);

【讨论】:

  • 感谢@ctn ..这有效。我也尝试过不使用 int **子集。像这样.. *p = (int **)malloc(a * sizeof(int *)); for( i = 0 ; i &lt; a ; i++) { (*p)[i] = (int *)malloc(b * sizeof(int)); } for(i = 0 ; i &lt; a ; i++) for(j = 0 ; j &lt; b ; j++) (*p)[i][j] = i+j; } 不明白为什么这不起作用。知道为什么吗?
  • @quirkystack 对我来说 void allocate2DArray(int ***p, int a, int b) { int i, j; *p = (int**)malloc(a*sizeof(int *)); for(i=0; i&lt;a; i++) (*p)[i] = (int*)malloc(b*sizeof(int)); for(i=0; i&lt;a; i++) for(j= 0; j&lt;b; j++) (*p)[i][j] = i+j; }main() { /* ... */ int **subset; allocate2DArray(&amp;subset, a, b); /* ... */ } 正在工作
  • 我的错误.. 在我的实际程序中没有在 *p 周围添加括号。谢谢
【解决方案2】:

您必须将int ***subset 传递给分配函数。这是因为参数是按值传递的。

【讨论】:

    【解决方案3】:

    你需要这个:

    void allocate2DArray(int ***subset, int a, int b)
    

    还有这个:

    allocate2DArray(&subset, a, b);
    

    【讨论】:

    • 这不起作用。编译时会给出两个警告:(1)assignment to ‘int ***’ from incompatible pointer type ‘int **’(2)assignment to ‘int **’ from incompatible pointer type ‘int *’。并在执行时给出分段错误。
    【解决方案4】:

    通过使用int **subset;,它不会变成二维数组。它仍然是一维存储,只是指向指针的指针。

    二维数组意味着指针缓冲区的每个元素必须指向一个由 ctn 建议的缓冲区。 他建议 ***ptr 和 *ptr 是 malloced ,它创建了缓冲区的第一维。 现在,当您再次调用 allocate2DArray() 时,子集被分配了创建第二维的内存。这验证了我上面的陈述——指针缓冲区的每个元素都必须指向一个缓冲区。

    现在使用建议的代码 -

     *p = (int **) malloc(a * sizeof(int *));
    

    创建了一个数组,其中每个元素都指向缓冲区“子集”,这完全创建了一个真正的二维数组。

    【讨论】:

      猜你喜欢
      • 2011-07-28
      • 2010-12-27
      • 2018-06-16
      • 2021-03-25
      • 2021-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-04
      相关资源
      最近更新 更多