在C语言中动态分配2D数组

在C语言中动态分配2D数组,c,pointers,memory-management,multidimensional-array,C,Pointers,Memory Management,Multidimensional Array,首先,我不是C编程专家,我现在正在阅读一些遗留C代码。在那里,我找到了以下用于初始化2D矩阵的函数: long int **computeDistanceMatrix(void){ long int i; long int j; long int ** matrix; matrix = malloc(sizeof(long int) * numberOfCities * numberOfCities + sizeof(long int *) * n

首先,我不是C编程专家,我现在正在阅读一些遗留C代码。在那里,我找到了以下用于初始化2D矩阵的函数:

long int **computeDistanceMatrix(void){
    long int i;
    long int j;
    long int ** matrix;
    matrix = malloc(sizeof(long int) * numberOfCities * numberOfCities +
        sizeof(long int *) * numberOfCities);

    if(matrix == NULL){
        fprintf(stderr, "Out of memory, exit.");
        exit(1);
    }

    for (i = 0; i < numberOfCities; i++){
        matrix[i] = (long int*) (matrix + numberOfCities) + i * numberOfCities;
        for (j = 0; j < numberOfCities; j++){
            matrix[i][j] = distanceFunction(i, j);
        }
    }
    return matrix;
}
long int**计算距离矩阵(void){
long int i;
long-int-j;
长整数**矩阵;
矩阵=malloc(sizeof(long int)*numberOfCities*numberOfCities+
sizeof(长整数*)*城市数量;
if(矩阵==NULL){
fprintf(stderr,“内存不足,退出”);
出口(1);
}
对于(i=0;i
我觉得代码有点奇怪,因为我期待着一些对我来说更清晰的东西。无论如何,我想知道以下几点:

  • malloc(sizeof(long int)*numberOfCities*numberOfCities+sizeof(long int*)*numberOfCities)
    意味着他们正在为数据项和指向每行的指针分配内存
  • 什么是矩阵[i]=(长整数*)(矩阵+numberOfCities)+i*numberOfCities?我真的不明白他们想做什么
  • 在C语言中,是否有一种更直接的方法来为2D数组分配内存,或者这是正确的方法

这是动态分配2D阵列的另一种方法

#include <stdlib.h>

int **array;
array = malloc(nrows * sizeof(int *));
if(array == NULL)
    {
    fprintf(stderr, "out of memory\n");
    exit(EXIT_FAILURE); //or return here
    }
for(i = 0; i < nrows; i++)
    {
    array[i] = malloc(ncolumns * sizeof(int));
    if(array[i] == NULL)
        {
        fprintf(stderr, "out of memory\n");
        exit(EXIT_FAILURE); //or return here
        }
    }
#包括
整数**数组;
数组=malloc(nrows*sizeof(int*);
if(数组==NULL)
{
fprintf(stderr,“内存不足”);
exit(exit_FAILURE);//或返回此处
}
对于(i=0;i
其主要思想是声明指向int指针的指针。这是您的矩阵(数组)。首先,动态分配第一个维度的大小,然后动态分配另一个整数指针数组

你真正需要理解的是,当你在内存中动态分配空间时,没有“维度”。它们只是一些随机的地方。记住这一点,你可以分配一个N-D维度数组并超越二维限制。

matrix[i]=(long int*)(matrix+numberOfCities)+i*numberOfCities

就像你自己说的,他们正在为数据和指针分配内存,数据将是连续的。但是分配数据是不够的,因为指针没有初始化(指向垃圾),所以现在他们必须将指针设置为实际指向数据

重要的是要理解他们所做的是,首先你有所有的指针,然后才有数据,比如:[ptr1,ptr2,ptr3,data1[],data2[],data3[]

现在让我们看看第一个指针-他应该指向数组的开始,因此如果
i=0
,那么我们得到
matrix[0]=(long int*)(matrix+numberOfCities)它指向数据段的开头


对于
i=1
我们得到
matrix[0]=(long int*)(matrix+numberOfCities)numberOfCities
在数据段开始后的“一个numberOfCities块”

首先
numberOfCities
矩阵的
项是
long int*
,它们指向允许写入
矩阵[i][j]
以到达元素(i,j)的对应行。以下字节被视为
long int

答案是:

1) 对

2)
matrix+numberOfCities
是指向第一个数据行的指针,但它仍然是
long int**
。然后将其转换为
long int*
,然后通过
i*numberOfCities
元素进一步移动(每个元素都是
long int


3) 您可以将内存分配为单个数组,并执行2D->1D索引计算。或者,您可以分配指针数组,然后为每行分配一个数组。或者,您可以分配指针数组,然后为所有数据分配数组,然后将指针设置为数据数组中的相应项,以便每个指针指向其行。

创建二维数组的简单方法是:

long** create2DArray(int rows, int cols)
{
    // create an array of long* pointers
    long** ptr = (long**) malloc(sizeof(long*) * rows);

    for(int i = 0; i < rows; i++)
    {
        // allocate an array for each row
        ptr[i] = (long*)malloc(sizeof(long) * cols));
    }
    return ptr;
}

int main()
{
    long int** ptr = create2DArray();
    return 0;
}
long**create2DArray(int行、int列)
{
//创建长*指针数组
long**ptr=(long**)malloc(sizeof(long*)*行);
对于(int i=0;i给定
sizeof(long int)=l
n
城市和
sizeof(long int*)=p
,这段代码尝试做的事情与。只需一次调用
malloc
,而不是多次调用

分配的第一个
np
字节用于保存
n
指针。每个指针都指向一个
nl
长整数块。当然,
long int
块都是相邻的,第一个块本身与
n
块、p大小的指针相邻,并且从地址
矩阵+np
开始

该行:
matrix[i]=(long int*)(matrix+numberOfCities)+i*numberOfCities

。。设置每个
n
指针以指向块中的正确位置。希望下面的ASCII艺术能让这一点变得足够清楚;)

我不知道这种“优化”(以降低可读性为代价)是否带来好处。有些可能是:

  • 它可能减少了
    malloc
    实现所需的簿记量。但也有额外的成本,我们现在计算点
    (addr = matrix +)  0    p    2p .. np   np+nl np+2nl
    
    [matrix]-------->[ v    v    v  .. ^    ^     ^
                       |    |    |     |    |     |
                       |____|____|_____|    |     |
                            |____|__________|     |
                                 |________________|
    
    double (*A)[n] = malloc(sizeof(double[n][n]));