C-在函数中分配矩阵

C-在函数中分配矩阵,c,function,matrix,malloc,C,Function,Matrix,Malloc,我正在尝试使用一个函数来分配一个矩阵,该函数接受它的维数和一个三重指针。我已经分配了一个int**(设置为NULL),并将其地址作为函数的参数传递。出于某种原因,这给了我一个mem访问冲突 void allocateMatrix(int ***matrix, int row, int col) { int i; if((*matrix = (int**)malloc(row * sizeof(int*))) == NULL) { perror("There

我正在尝试使用一个函数来分配一个矩阵,该函数接受它的维数和一个三重指针。我已经分配了一个int**(设置为NULL),并将其地址作为函数的参数传递。出于某种原因,这给了我一个mem访问冲突

void allocateMatrix(int ***matrix, int row, int col)
{
    int i;
    if((*matrix = (int**)malloc(row * sizeof(int*))) == NULL)
    {
        perror("There has been an error");
        exit(EXIT_FAILURE);
    }
    for(i = 0; i < row; ++i)
    {
        if((*matrix[i] = (int*)malloc(col * sizeof(int))) == NULL)
        {
            perror("There has been an error");
            exit(EXIT_FAILURE);
        }
    }
}

/* main.c */

    int** matrix = NULL;
    allocateMatrix(&matrix, MATRIX_ROW, MATRIX_COL); //error
void分配器矩阵(int***矩阵,int行,int列)
{
int i;
if((*matrix=(int**)malloc(row*sizeof(int*))==NULL)
{
perror(“出现了错误”);
退出(退出失败);
}
对于(i=0;i
您需要更改

if((*matrix[i] = (int*)malloc(col * sizeof(int))) == NULL)

在使用数组下标之前,需要取消对矩阵的引用。

*矩阵[i]
相当于
*(矩阵[i])

这是一个运算符优先级问题。在

if ((*matrix[i] = (int*)malloc( ... ))
默认优先级为
*(矩阵[i])
,而您应该使用
(*matrix)[i]


我仍然建议将矩阵分配为一个连续数组,而不是数组指针数组。

我已经为gcc C11/C99制定了一个解决方案,并基于链接提供了适当的分配功能:

在注释中进行了一些讨论之后,很明显matrix2已正确分配,可以将其作为matrix2[0](一维数组中的数据)传递给函数fn(int row,int col,int array[col][row]),并强制转换为(double(*)[])

//使用gcc编译--std=c11 program.c
#包括
#包括
#定义MX9
#定义我的14
无效输入_矩阵(int行、int列、双矩阵[行][列]);
无效打印矩阵(整数行、整数列、双矩阵[行][列]);
双**分配矩阵2(整数行,整数列);
双*alloc_matrix3(int行,int列);
void*alloc_matrix4(int行,int列);
int main()
{
int i=MX,j=MY;
printf(“使用函数fn(int w,int k,双矩阵[w][k])(在C99和C11中)生成输入值和打印矩阵”);
双矩阵1[i][j];
输入_矩阵(MX,MY,matrix1);
printf(“矩阵静态\n”);
打印矩阵(MX、MY、matrix1);
double**matrix2;//matrix2的数据就是matrix3
matrix2=alloc_matrix2(MX,MY);
输入矩阵(MX,MY,(double(*)[])(*matrix2));
printf(“两次分配一个用于指针的矩阵,第二次用于数据(double(*)[]))(m[0])\n”);
打印矩阵(MX,MY,(double(*)[])(matrix2[0]);
免费(*2);
免费(2);
double*matrix3=alloc_matrix3(MX,MY);
输入矩阵(MX,MY,(双(*)[])矩阵3);
printf(“分配为二维数组的矩阵\n”);
打印矩阵(MX,MY,(双(*)[])矩阵3);
免费(3);
j=我的;
双(*matrix4)[j];
matrix4=(双(*)[])alloc_matrix4(MX,MY);
输入矩阵(MX、MY、matrix4);
printf(“通过指向数组m的指针分配的矩阵=(double(*)[])malloc(MX*sizeof(*m))\n”);
打印矩阵(MX、MY、matrix4);
免费(matrix4);
printf(“\n结束!\n”);
返回0;
}
无效输入矩阵(整数行、整数列、双矩阵[行][列]){

对于(int i=0;i您的结构效率低下。请使用单个数组而不是数组数组,并使用
[y*width+x]
@Dave进行访问,我知道,但是指针算法已经够可怕的了…@Venom如果只有一个指针,而不是指向指针数组的指针,那不是更可怕吗?:)@海德也许我以后会修改它,尺寸小到足以防止效率低下的现象出现。我知道马洛克及其衍生物相当昂贵。我现在不知道该接受哪一种。你是第一个回答的人,但没有解释。这对你来说可能是微不足道的:)@Venom很高兴它为你解决了。你可以向上投票并接受多个答案,因此如果有多个答案帮助您,您可以识别多个答案:-)matrix2
版本导致未定义的行为(
T**
T(*)[n]
)不同。将编译器错误隐藏在强制转换后不会修复任何问题。matrix3和marix4,代码正常(它有可以删除的不必要的强制转换),但注释是错误的。
matrix4
是通过指向数组的指针(而不是指向数组的指针数组)分配的@Matt McNabb:我添加了一些新的评论。你能解释一下为什么matrix4只是通过指向数组的指针生成的,而不是MX维度的数组吗?matrix2的解决方案正在发挥作用:它与matrix3一样,但有一个额外的指针数组。matrix2的数据是一维数组。matrix2不起作用,你有一个锯齿数组allocated正确,但无法将其传递给需要连续内存块的函数。input_matrix函数将在第一行末尾的未分配内存上涂鸦(print_matrix函数读取相同的内存)。在matrix4中,您分配了一个数组,每个数组的元素都是另一个数组。返回的是指向外部数组第一个元素的指针。@Matt McNabb:所以这个站点解决方案是正确的。他们使用了指针数组的这种设计。但是print_matrix是否可以读取未分配的内存?如何在代码中证明它?
if ((*matrix[i] = (int*)malloc( ... ))
//compile with gcc --std=c11 program.c
#include <stdio.h>
#include <stdlib.h>

#define MX 9
#define MY 14

void input_matrix(int row, int column, double matrix[row][column]);
void print_matrix(int row, int column, double matrix[row][column]);
double **alloc_matrix2(int row, int column);
double  *alloc_matrix3(int row, int column);
void    *alloc_matrix4(int row, int column);

int main()
{
    int i=MX, j=MY;
    printf("Generate input values and print matrices with functions fn(int w, int k, double matrix[w][k]) (in C99 and C11)\n");
    double matrix1[i][j];
    input_matrix(MX,MY,matrix1);
    printf("matrix static\n");
    print_matrix(MX,MY,matrix1);


    double **matrix2; //data of matrix2 is just matrix3                 
    matrix2=alloc_matrix2(MX,MY); 
    input_matrix(MX,MY,(double (*)[])(*matrix2));
    printf("matrix two times allocated one for pointers, the second for data (double (*)[])(m[0])\n");
    print_matrix(MX,MY,(double (*)[])(matrix2[0]));
    free(*matrix2);
    free(matrix2);


    double *matrix3=alloc_matrix3(MX,MY);
    input_matrix(MX,MY,(double (*)[])matrix3);
    printf("matrix allocated as two-dimensional array\n");
    print_matrix(MX,MY,(double (*)[])matrix3);
    free(matrix3);

    j=MY;
    double (*matrix4)[j];
    matrix4 = (double (*)[])alloc_matrix4(MX,MY);
    input_matrix(MX,MY,matrix4);
    printf("matrix allocated via pointer to array m = (double (*)[])malloc(MX * sizeof(*m))\n");
    print_matrix(MX,MY,matrix4);
    free(matrix4);
    printf("\nThe End!\n");
    return 0;
}

void input_matrix(int row, int column, double matrix[row][column]){
    for(int i=0; i<row; i++){
        for(int j=0; j<column; j++)
            matrix[i][j]=i+1;
    }
}

void print_matrix(int row, int column, double matrix[row][column]){
    for(int i=0; i<row; i++){
        for(int j=0; j<column; j++)
            printf("%.2lf ", matrix[i][j]);
        printf("\n");
    }
}

double **alloc_matrix2(int row, int column){
    double **matrix;
    matrix=malloc(row*sizeof(double*));
    matrix[0] = (double *)malloc(row*column*sizeof(double));
    for(int i = 1; i < row; i++)
        matrix[i] = matrix[0]+i*column;
    return matrix;
}

double *alloc_matrix3(int row, int column){
    double *matrix;
    matrix=malloc(row*column*sizeof(double));
    return matrix;
}

void *alloc_matrix4(int row, int column){
    double (*matrix)[column];
    matrix = (double (*)[])malloc(row*sizeof(*matrix));
    return matrix;
}