3

这可能是一个非常愚蠢的问题。
我正在使用 malloc 进行内存分配。
程序编译正常,但启动时出现分段错误。
这是最小代码:

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

int main()
{
    int row,col,i;
    int **mat;
    row = 3; //made row as static for testing
    col = 4; //made col as static for testing
    *mat = (int *)malloc(sizeof(int)*row);
    for (i=0;i<row;i++)
       mat[i] = (int *) malloc (sizeof(int)*col);
}

我在 gdb 上使用 gcc -ggdb test.c 编译
它的给定:

(gdb) run
Starting program: /slowfs/swe91/abjoshi/clients/fw_cl_for_seg_fault/a.out

Program received signal SIGSEGV, Segmentation fault.
0x00000000004004cc in main () at 1test.c:10
10          *mat = (int *)malloc(sizeof(int)*row);

注意:gcc 版本 4.5.2

4

5 回答 5

9

常见的用法如下:分配指针指向malloc的元素数组使用以下通用语法np

p = malloc(n * sizeof *p);

这将帮助您避免代码中的错误。注意这里的关键点:不要转换结果,malloc也不要使用sizeof. 一般来说:尽可能避免在声明之外的任何地方提及类型。

在您的情况下,第一个分配应如下所示

mat = malloc(row * sizeof *mat);

循环内的分配应如下所示

for (i = 0; i < row; ++i)
   mat[i] = malloc(col * sizeof *mat[i]);

这种方法的重要好处是代码与类型无关:您可以随时更改matfrom的声明int **mat,例如double **mat,但分配代码将继续保持有效 - 您不必在此处进行任何更改.

于 2013-09-18T18:28:12.990 回答
3

代替

*mat = (int *)malloc(sizeof(int)*row);

我想你想要

mat = (int **)malloc(sizeof(int *) * row);

实际上,您正在取消引用未初始化的 mat 。你需要 malloc() mat 在你尊重它之前。

你也可以离开 malloc 的演员表:

mat = malloc(sizeof(int *) * row);

以及 sizeof(int *) 参考:

mat = malloc( row * sizeof(*mat));
于 2013-09-18T18:23:29.393 回答
2

编译器会用 -Wall 告诉它

$ gcc -Wall y.c
y.c: In function ‘main’:
y.c:14:1: warning: control reaches end of non-void function [-Wreturn-type]
y.c:11:8: warning: ‘mat’ is used uninitialized in this function [-Wuninitialized]
于 2013-09-18T18:29:57.220 回答
1

*mat = (int *) malloc(sizeof(int)*row);您尝试取消引用 mat 的行中。mat 当前未初始化。

于 2013-09-18T18:23:37.043 回答
0

这是什么:

mat是一个双指针,它是未初始化的(或 NULL)。当您取消引用它时:

*mat = (int *)malloc(sizeof(int)*row);

您正在取消引用 NULL 值并尝试分配给它,从而导致分段错误。

首先使用指向 (int*) 指针列表的指针初始化 mat。然后单独获取列表中的每个指针并为每个指针分配(int)空间。

mat = (int *)malloc(cols*sizeof(int *));
for (i=0;i<cols;i++)
    mat[i] = malloc(rows*sizeof(int))
于 2013-09-18T18:34:27.720 回答