功能动态分配矩阵 [英] Function to dynamically allocate matrix

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

问题描述

我想创建一个函数来分配(用的malloc / 释放calloc )声明为双指针的矩阵。我理解的双指针的矩阵是如何工作的,以及如何与的malloc 分配它,但是当我通过我的基质(在宣布的main()并初始化为 NULL )我的程序崩溃。我想,错误的是我的 allocMatrix()函数,因为如果我分配在矩阵主一切工作顺利进行。感谢: - )

主营:

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括Data.h#定义ROW 5
#定义COL 5诠释主要(无效){    INT I,J,RET;
    INT nRow,NCOL;
    INT **垫= NULL; //双指针的矩阵    nRow = 0;
    NCOL = 0;    行和列//插入N
    的printf(插入的行和列的n个:\\ n);
    scanf函数(%D,&安培; nRow,&安培; NCOL);    //功能分配矩阵
    RET = allocMatrix(垫,nRow,NCOL);
    的printf(返回值数:%d \\ n,RET);    / *
    这code完美的作品!
    垫=的malloc(nRow *的sizeof(INT));
    I = 0;
    而(I< nRow)
    {
        垫[I] =的malloc(NCOL *的sizeof(INT));
        我++;
    }
    * /    //从标准输入值
    I = 0;
    而(I< nRow)
    {
        J = 0;
        而(J< NCOL)
        {
            的printf(插入值POS [%D,%D]。:\\ n,I,J);
            scanf函数(%d个,&安培;垫[I] [J]);
            J ++;
        }
        我++;
    }    //打印值
    I = 0;
    而(I< nRow)
    {
        J = 0;
        而(J< NCOL)
        {
            的printf(价值POS [%D,%D]。为:%d个\\ N,I,J,垫[I] [J]);
            J ++;
        }
        我++;
    }
    系统(暂停);
    返回EXIT_SUCCESS;
}

allocateMatrix 功能:

  INT allocMatrix(INT **矩阵,诠释nRow,诠释NCOL)
{
    INT I;
    INT ext_status;    //矩阵经典配置方法
    矩阵=的malloc(nRow *的sizeof(INT));    如果(矩阵!= NULL)
    {
        I = 0;
        而(I< nRow)
        {
            矩阵[I] =的malloc(NCOL *的sizeof(INT));            如果(矩阵[I]!= NULL)
                ext_status = 1;
            其他
                ext_status = 0;
            我++;
        }
    }
    其他
        ext_status = 0;    返回ext_status;
 }


解决方案

切勿使用指针到指针分配多维数组。它是宽-S $ P $垫,但坏的和不正确的做法。这样做不会给你一个真实的二维数组,这会导致由于堆碎片的速度较慢code。这也使得code更难写入,读取和维护,这反过来又增加了潜在的存储器泄露。

相反,正确地分配二维阵列中的相邻的存储单元,是这样的:

  INT X;
诠释Ÿ;//存储在x和y一些值这里INT(*矩阵)[Y] =的malloc(sizeof的(INT [X] [Y]));如果(矩阵== NULL)
{
  //的错误处理
}矩阵[I] [J] =东西; //做一些与基体免费(矩阵);

如果你坚持保持此code的功能,那么这将是:

 无效* allocMatrix(INT nRow,诠释NCOL)
{
  返回的malloc(sizeof的(INT [nRow] [NCOL]));
}INT(*矩阵)[Y] = allocMatrix(X,Y);


编辑:在code和指针数组的解释

在该行 INT(*矩阵)[Y] =的malloc(sizeof的(INT [X] [Y])); 的sizeof(INT [X] [Y])是pretty直线前进,它与尺寸X * Y整数的二维数组的只是大小。它使用来自C99标准,它允许在运行时指定数组维变长数组的概念。

这是数组指针的是在C有点特殊类型,它能够指向整个阵列,而不是仅仅在数组的第一个项目,作为一个正常的指针就行了。阵列的指针,不象常规的指针,知道数组的大小。

这是数组指针写成键入(*名称)【尺寸】,因此,例如数组指针5 int数组将被写成 INT(* arr_ptr)[5] =&放大器; the_array;

在访问的内容指向,数组指针行为就像任何指针,您可以访问它的内容与 * 。因此, * arr_ptr 给出了阵列指向和(* arr_ptr)[0] 给出了数组的第一个项目。

有关多维数组,适用同样的规则。鉴于阵列 INT ARR [X] [Y] ,数组指针,这种类型将是 INT(* arr_ptr)[X] [Y] =安培;改编; 。访问内容 * arr_ptr 会给你一个二维数组,这相当于一个数组的数组。 (* arr_ptr)[0] 也会因此给数组的数组中的第一个数组。在离pression使用时任何数组名称通常的规则,是它衰变成一个指向第一个元素。亦如在这里,所以(* arr_ptr)[0] 将因此也成为同一个指向第一个数组的第一个元素。和(* arr_ptr)[0] [0] 将给予第一个数组的第一个元素。

现在这种语法(* arr_ptr)[0] [0] 看起来有点难以阅读;得到一个二维数组的第一个项目,我们是在只是写使用改编[0] [0] 。因此,声明数组指针的时候,有一个方便的窍门。相反,声明完整和正确的数组指针: INT(*矩阵)[X] [Y] ,数组指针尺寸的二维数组X * Y,我们只好声明为 INT(*矩阵)[Y] ,这是一个数组的指针一维数组与尺寸Y。这将指向二维数组,这是大小y的一维数组中的第一项。我们知道,二维数组包含x,使得项目。

而因为这一招,我们现在可以使用数组指针具有相同的语法访问二维数组,即矩阵作为时,由[i] [j]的,而不是难以阅读(*矩阵)[I] [J]

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 :-)

Main:

#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:\n");
    scanf("%d %d", &nRow, &nCol);

    //Functions to allocate matrix
    ret=allocMatrix(mat, nRow, nCol);
    printf("Return value: %d\n",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]:\n", 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 \n", i, j, mat[i][j]);
            j++;
        }
        i++;
    }


    system("pause");
    return EXIT_SUCCESS;
}

allocateMatrix function:

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;
 }

解决方案

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);


Edit: explanation of the code and array pointers.

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.

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.

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;.

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.

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.

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.

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天全站免登陆