当您创建一个数组时,例如 int myArray[10][20],会从堆栈中分配一个有保证的连续内存块,并使用普通数组算法来查找数组中的任何给定元素。
如果要从堆中分配该 3D“数组”,请使用 malloc() 并取回一些内存。那个记忆是“愚蠢的”。它只是一块内存,应该被认为是一个向量。阵列的导航逻辑都没有附带,这意味着您必须找到另一种方法来导航所需的 3D 阵列。
由于您对 malloc() 的调用返回一个指针,因此您需要的第一个变量是一个用于保存 int* 向量的指针,您将需要保存一些实际的整数数据 IE:
整数 *pArray;
...但这仍然不是您要存储整数的存储空间。你所拥有的是一个指针数组,目前没有指向任何东西。要获取数据的存储空间,您需要调用 malloc() 10 次,每个 malloc() 在每次调用时为 20 个整数分配空间,其返回指针将存储在 *pArray 指针向量中。这意味着
整数 *pArray
需要改为
int **pArray
正确地表明它是一个指向指针向量基数的指针。
第一个解引用 *pArray[i] 将您置于 int 指针数组的某个位置,第二个解引用 *p[i][j] 将您置于 int 数组中的某个位置,由 int 指针指向数组[i]。
IE:你有一堆散布在堆上的整数向量,由一组指针指向,跟踪它们的位置。与从堆栈中静态分配的 Array[10][20] 完全不同,后者都是连续存储,并且在任何地方都没有单个指针。
正如其他人所逃避的那样,基于指针的堆方法乍一看似乎没什么用,但事实证明它非常优越。
首先,最重要的是,您可以随时使用 free() 或 realloc() 来调整堆内存的大小,并且在函数返回时它不会超出范围。更重要的是,有经验的 C 编码人员尽可能安排他们的函数对向量进行操作,其中在函数调用中删除了 1 级间接。最后,对于大型数组,相对于可用内存,特别是在大型共享机器上,大块连续内存通常不可用,并且对其他需要内存才能运行的程序不友好。在堆栈上分配的具有大型静态数组的代码是维护的噩梦。
在这里您可以看到该表只是一个收集从向量操作返回的向量指针的外壳,其中所有有趣的事情都发生在向量级别或元素级别。在这种特殊情况下,VecRand() 中的向量代码是 calloc() 处理它自己的存储并将 calloc() 的返回指针返回到 TblRand(),但 TblRand 也可以灵活地分配 VecRand() 的存储,只需通过调用 calloc() 替换 VecRand() 的 NULL 参数
/*-------------------------------------------------------------------------------------*/
dbl **TblRand(dbl **TblPtr, int rows, int cols)
{
int i=0;
if ( NULL == TblPtr ){
if (NULL == (TblPtr=(dbl **)calloc(rows, sizeof(dbl*))))
printf("\nCalloc for pointer array in TblRand failed");
}
for (; i!=rows; i++){
TblPtr[i] = VecRand(NULL, cols);
}
return TblPtr;
}
/*-------------------------------------------------------------------------------------*/
dbl *VecRand(dbl *VecPtr, int cols)
{
if ( NULL == VecPtr ){
if (NULL == (VecPtr=(dbl *)calloc(cols, sizeof(dbl))))
printf("\nCalloc for random number vector in VecRand failed");
}
Randx = GenRand(VecPtr, cols, Randx);
return VecPtr;
}
/*--------------------------------------------------------------------------------------*/
static long GenRand(dbl *VecPtr, int cols, long RandSeed)
{
dbl r=0, Denom=2147483647.0;
while ( cols-- )
{
RandSeed= (314159269 * RandSeed) & 0x7FFFFFFF;
r = sqrt(-2.0 * log((dbl)(RandSeed/Denom)));
RandSeed= (314159269 * RandSeed) & 0x7FFFFFFF;
*VecPtr = r * sin(TWOPI * (dbl)(RandSeed/Denom));
VecPtr++;
}
return RandSeed;
}