在C语言中动态分配2D数组
首先,我不是C编程专家,我现在正在阅读一些遗留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
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数组分配内存,或者这是正确的方法
#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]));