动态分配矩阵的函数 [英] Function to dynamically allocate matrix

查看:23
本文介绍了动态分配矩阵的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个函数来分配(使用malloc/calloc)一个声明为双指针的矩阵.我了解双指针矩阵的工作原理以及如何使用 malloc 分配它,但是当我传递我的矩阵(在 main() 中声明并初始化为 NULL) 我的程序崩溃了.我想错误出在我的 allocMatrix() 函数上,因为如果我在 main 中分配矩阵,一切都会顺利进行.谢谢:-)

I want to create a function to allocate (with malloc/calloc) a matrix declared as a double pointer. I understood how a double pointer matrix works and how allocate it with malloc, but when I pass my matrix (declared in main() and initialized to NULL) my program crashes. I suppose that the error is with my allocMatrix() function because if I allocate the matrix in main all works smoothly. Thanks :-)

主要内容:

#include <stdio.h>
#include <stdlib.h>
#include "Data.h"

#define ROW 5
#define COL 5

int main(void) {

    int i,j, ret;
    int nRow, nCol;
    int **mat=NULL; // double pointer matrix

    nRow = 0;
    nCol = 0;

    //Insert n of row and columns
    printf("Insert n of rows and columns:
");
    scanf("%d %d", &nRow, &nCol);

    //Functions to allocate matrix
    ret=allocMatrix(mat, nRow, nCol);
    printf("Return value: %d
",ret);

    /*
    this code works perfect!
    mat= malloc(nRow * sizeof(int));
    i=0;
    while( i < nRow)
    {
        mat[i]=malloc(nCol * sizeof(int));
        i++;
    }
    */

    //Get Values from stdin
    i=0;
    while( i < nRow)
    {
        j=0;
        while (j < nCol)
        {
            printf("Insert value pos[%d,%d]:
", i, j);
            scanf("%d", &mat[i][j]);
            j++;
        }
        i++;
    }

    //Print values
    i=0;
    while (i < nRow)
    {
        j=0;
        while( j < nCol)
        {
            printf("Value pos[%d,%d] is: %d 
", i, j, mat[i][j]);
            j++;
        }
        i++;
    }


    system("pause");
    return EXIT_SUCCESS;
}

allocateMatrix 函数:

int allocMatrix(int **matrix, int nRow, int nCol)
{
    int i;
    int ext_status;

    //Classic allocation method for matrix
    matrix= malloc( nRow * sizeof(int));

    if ( matrix != NULL)
    {
        i=0;
        while (i < nRow)
        {
            matrix[i]= malloc(nCol * sizeof(int));

            if( matrix[i] != NULL)
                ext_status= 1;
            else
                ext_status= 0;
            i++;
        }
    }
    else
        ext_status= 0;

    return ext_status;
 }

推荐答案

永远不要使用指针到指针来分配多维数组.这是普遍但糟糕和不正确的做法.这样做不会给你一个真正的 2D 数组,而且会因为堆碎片而导致代码变慢.它还使代码更难编写、阅读和维护,从而增加了内存泄漏的可能性.

Never use pointer-to-pointer to allocate multi-dimensional arrays. It is wide-spread but bad and incorrect practice. Doing so will not give you a true 2D array, and it will lead to slower code because of heap fragmentation. It also makes the code harder to write, read and maintain, which in turn increases the potential for memory leaks.

相反,在相邻的内存单元中正确分配二维数组,如下所示:

Instead, allocate the 2D array correctly in adjacent memory cells, like this:

int x;
int y;

// store some values in x and y here

int(*matrix)[y] = malloc (sizeof(int[x][y]));

if(matrix == NULL)
{
  // error handling here
}

matrix[i][j] = something; // do something with the matrix

free(matrix);

如果你坚持将这段代码保留在一个函数中,那么它会是:

If you insist on keeping this code in a function, then it would be:

void* allocMatrix (int nRow, int nCol)
{
  return malloc (sizeof(int[nRow][nCol]));
}

int(*matrix)[y] = allocMatrix(x, y);

<小时>

代码和数组指针的解释.


explanation of the code and array pointers.

int(*matrix)[y] = malloc (sizeof(int[x][y])); 行中,sizeof(int[x][y]) 非常简单,它只是维度为 x*y 的二维整数数组的大小.它使用了来自 C99 标准的可变长度数组的概念,允许在运行时指定数组维度.

In the line int(*matrix)[y] = malloc (sizeof(int[x][y]));, the sizeof(int[x][y]) is pretty straight-forward, it is just the size of a 2D array of ints with dimensions x*y. It is using the concept of variable-length arrays from the C99 standard, which allows array dimensions to be specified in runtime.

数组指针在 C 中是一种有点特殊的类型,它能够指向整个数组,而不是像普通指针那样只指向数组的第一项.数组指针与普通指针不同,它知道数组的大小.

An array pointer is a somewhat special type in C, it is able to point to whole arrays, rather than just at the first item of the array, as a normal pointer will do. The array pointer, unlike a regular pointer, knows the size of the array.

一个数组指针写成type(*name)[size],所以例如一个指向5个整数数组的数组指针将写成int(*arr_ptr)[5] = &the_array;.

An array pointer is written as type(*name)[size], so for example an array pointer to an array of 5 ints would be written as int(*arr_ptr)[5] = &the_array;.

当访问指向的内容时,数组指针的行为就像任何指针一样,你可以用*访问它的内容.所以 *arr_ptr 给出指向的数组,而 (*arr_ptr)[0] 给出该数组的第一项.

When accessing the contents pointed at, an array pointer behaves just as any pointer, you access the contents of it with *. So *arr_ptr gives the array pointed at, and (*arr_ptr)[0] gives the first item of that array.

对于多维数组,同样的规则适用.给定数组 int arr[x][y],指向该类型的数组指针将是 int(*arr_ptr)[x][y] = &arr;.访问内容 *arr_ptr 会给你一个二维数组,相当于数组的数组.(*arr_ptr)[0] 因此将给出数组数组中的第一个数组.在表达式中使用任何数组名称时,通常的规则是它衰减"为指向第一个元素的指针.同样适用于此,因此 (*arr_ptr)[0] 因此也将与指向第一个数组中第一个元素的指针相同.而 (*arr_ptr)[0][0] 将给出第一个数组的第一个元素.

For multi-dimensional arrays, the same rules apply. Given the array int arr[x][y], an array pointer to this type will be int(*arr_ptr)[x][y] = &arr;. Accessing the contents *arr_ptr will give you a two-dimensional array, which is equivalent to an array of arrays. (*arr_ptr)[0] will therefore give the first array in the array of arrays. The usual rule for any array name when used in an expression, is that it "decays" into a pointer to the first element. Same applies here, so (*arr_ptr)[0] will therefore also be the same as a pointer to the first element in the first array. And (*arr_ptr)[0][0] will give the first element of the first array.

现在这个语法 (*arr_ptr)[0][0] 看起来有点难以阅读;要获取二维数组的第一项,我们只需要编写 arr[0][0].所以在声明数组指针时,有一个方便的技巧.我们没有声明完整且正确的数组指针:int(*matrix)[x][y],一个指向维度为 x*y 的二维数组的数组指针,而是将其声明为 int(*matrix)[y],它是一个数组指针,指向一个维度为 y 的一维数组.它将指向二维数组中的第一项,这是一个大小为 y 的一维数组.我们知道二维数组包含 x 个这样的项目.

Now this syntax (*arr_ptr)[0][0] looks a bit hard to read; to get the first item of a 2D array, we are used at writing just arr[0][0]. So when declaring the array pointer, there is a handy trick. Instead of declaring the complete and correct array pointer: int(*matrix)[x][y], an array pointer to a 2D array of dimensions x*y, we instead declare it as int(*matrix)[y], which is an array pointer to a 1D array with dimension y. It will point at the first item in the 2D array, which is a 1D array of size y. We know that the 2D array contains x such items.

由于这个技巧,我们现在可以使用与访问二维数组时语法相同的数组指针,即matrix[i][j],而不是难以阅读的(*matrix)[i][j].

And because of this trick, we'll now be able to use the array pointer with the same syntax as when accessing a 2D array, namely matrix[i][j], rather than the hard-to-read (*matrix)[i][j].

这篇关于动态分配矩阵的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆