指针指向动态内存分配困惑
我很难完全理解正在发生的事情。
这是我阅读底部代码的方式。
将A定义为指向指向double地址的指针地址的指针。
在堆上分配4块内存,每块内存可以将地址保存为一倍。 返回分配给A的第一个块的地址
在堆上分配6个内存块,每个内存块可以保存一个双数据类型,并为之前分配的4个块中的每个块返回第一个块的地址。
变量A仍然包含四个指针中第一个块的地址,前提是A [0]改变了A指向的地址的值而不是A本身。
现在,这是图表进入底部的链接。 假设我想访问存储在红色块中的数据。 我会怎么做?
下面的代码会起作用吗?
double data = *(*(A + 3) + 2);
我的逻辑是,A是一个指针,递增3,应增加地址大小的字节数(double *)。 解引用地址(A + 3),我会得到第一个块的地址(假设它没有被重新分配)。 通过将结果地址增加2并取消引用该地址,我应该获得红色块的值。
所以如果我理解正确的话,1 + M指针被存储在内存中。 为什么? 如果目标是存储MxN数据,为什么我需要1 + M指针才能这样做? 如果我想要定义不同大小的行,但额外的指针看起来像是有帮助的,但目标是定义一个矩形的数据数组。
const int M = 4;
const int N = 6;
double **A;
A = malloc(M*sizeof(double *));
for (i = 0; i < N; i++) {
A[i]= malloc(N*sizeof(double));
}
图:
注意:我是电气工程专业的学生,在某种程度上不熟悉C语言和正式的编程习惯。 我知道我对这样一段简单的代码很迂腐,但我想确定我正确理解指针和内存分配。 乍一看很难理解。 这是我的教授给我的矩阵乘法代码的一部分,我想将指针传递给一个函数,并让它访问并修改内存中的正确值。 个人会喜欢看这个代码的二维数组,但我假设有一个很好的理由。
你也可以连续存储它,只需要做数学计算而不是让编译器为你做
所以:
double * A = malloc (M * N * sizeof(double));
double get(double * what, cur_x, cur_y, max_x, max_y)
{
return *(what+cur_x*max_y+cur_y);
}
这将节省所有的间接性,因为你知道尺寸
如果你不需要动态分配尺寸,这是什么
double A[17][14]
会在堆叠中为你做
是的, double data = *(*(A + 3) + 2);
将工作,并访问“红色”双。
我想你的教授会很快告诉你A[3][2]
适用,阅读起来要容易得多,而且优于*(*(A + 3) + 2);
获得的教训(还没有,但你的教授想要教给你什么):在C中,多维数组不是像'具有N列和M行的表',在C中,所有数组都是指针,而多维数组被实现为指向指针的指针。 每当你写A[3][2]
, *(*(A + 3) + 2)
是内部真正发生的事情。 这反过来解释了为什么你不能在一个语句中分配N * M矩阵; 您必须首先分配“行指针”,然后为每个行指针分配“列”。
malloc(M*sizeof(double *))
说:“给我一个指向M个双指针的指针。” malloc(N*sizeof(double))
说:“给我一个指向N个双打的指针。” 现在注意这个错误:
for (i = 0; i < N; i++) {
A[i]= ...;
}
A
指向一个M双指针数组,但是你正在写入N个条目(其中每个条目都是指向N个双精度的指针)。 如果M > N
,则浪费空间,如果M < N
,则使用您没有要求写入的空间。
上一篇: Confused about Pointers to Pointers and Dynamic Memory Allocation
下一篇: Where will the memory allocation for a string in C will take place