为什么我在C中的多维动态分配不起作用?

我一直试图弄清楚我在C中分配和使用多维动态分配数组的问题。我真的很感激任何帮助。

我尝试了两种方法。 首先:

cdr = (double ***) malloc(NUM_REGIONS * sizeof(double **)); for(i=0; i<NUM_REGIONS; i++){ cdr[i] = (double **) malloc(numRatings * sizeof(double *)); for(j=0; j<numRatings; j++){ cdr[i][j] = (double *) malloc(remQuarters * sizeof(double)); } } 

第二个:

 tempPtr1 = (double *) malloc(NUM_REGIONS * numRatings * remQuarters * sizeof(double) ); tempPtr2 = (double **) malloc (NUM_REGIONS * numRatings * sizeof(double *)); cdr = (double ***) malloc(NUM_REGIONS * sizeof(double **)); for(i=0; i< NUM_REGIONS; i++){ cdr[i] = tempPtr2 + i; for(j=0; j < numRatings; j++) cdr[i][j] = tempPtr1 + i * NUM_REGIONS + j; } 

两者都不起作用。 在这两种情况下,每个cdr [i]最终都指向同一个地方。 第一次进入’i’循环时,所有cdr [i](即cdr [0],cdr [1],cdr [2]等)都设置为相同的值。 然后,后续循环不会更改它们中的任何一个。

我怀疑运算符优先级正在发生什么,或者我的解引用错误,但我无法弄明白。

谢谢。

UPDATE

我把以下简化代码放在一起,似乎工作正常。 但是虽然输出完全符合预期,但我仍然会在调试器中逐步完成相同的奇怪行为。 我开始认为我的代码的基本问题可能在其他地方,并且我刚刚被调试器的问题所转移(或者可能只是因为我对输出的误解)。 是否有一个众所周知的原因,为什么Visual Studio中的’cdr [0]’,’cdr [1]’等手表无法显示我期望它显示的内容?

 #include "stdafx.h" #include "stdio.h" #include "stdlib.h" #define NUM_REGIONS 50 void printArray(double *inVec, int len){ int i; for(i=0; i<len; i++) printf("%f\t",inVec[i]); printf("\n"); } int main(array ^args){ int numRatings = 25, remQuarters = 100, i, j, k; double ***cdr; char dummy; cdr = (double ***) malloc(NUM_REGIONS * sizeof(double **)); for(i=0; i<NUM_REGIONS; i++){ cdr[i] = (double **) malloc(numRatings * sizeof(double *)); for(j=0; j<numRatings; j++){ cdr[i][j] = (double *) malloc(remQuarters * sizeof(double)); } } for(i=0; i<NUM_REGIONS; i++){ for(j=0; j<numRatings; j++){ for(k=0; k<remQuarters; k++){ cdr[i][j][k] = 100*i + 10*j +k; } } } for(i=0; i<5; i++) printf("%f\t",cdr[1][1][i]); printf("\n"); for(i=0; i<5; i++) printf("%f\t",cdr[3][1][i]); printf("\n"); for(i=0; i<5; i++) printf("%f\t",cdr[1][3][i]); printf("\n"); for(i=0; i<5; i++) printf("%f\t",cdr[i][i][i]); printf("\n"); printArray(cdr[1][1], 5); printArray(cdr[3][3], 5); scanf("%c", &dummy); return 0; } 

再次感谢所有反馈。

很久以前在大学时我得出结论,C中的多维数组应该用1D数组进行模拟。 第一个需要分配足够大的缓冲区来容纳所有元素。 对于将为ncolumns*nrows*sizeof(element)的2D数组。 然后通过将多维索引转换为1D索引来访问数组元素。 对于2Darrays,访问A(i,j)转换为bufA[i*ncolumns+j]

问题出在你的解除引用上。 cdr[i][j]不会做你想要的。 分配cdr[i] ,您将指针放在该索引处。 但是, cdr[i][j]不解除引用cdr[i] 。 它假设你有一个矩形的内存块,并为cdr添加适当的值以确定cdr[i][j]存在位置。 您可能需要使用* s手动取消引用。

我很难确定你到底遇到了什么问题。

我尝试了下面的多维数组双打并没有问题:

 int i, j; int rows = 5; int columns = 10; int z_axis = 5; double ***cdr = malloc(rows * sizeof(double **)); for (i = 0; i < rows; i++) { cdr[i] = malloc(columns * sizeof(double *)); for (j = 0; j < columns; j++) { cdr[i][j] = malloc(z_axis * sizeof(double)); } } 

有关此问题的详细信息,请参阅c-faq: http : //c-faq.com/aryptr/dynmuldimary.html

什么是cdr应该是什么? 一个双3D的数组(这是我假设的,基于你的片段)? 指向双倍的2D数组? 或指向2D数组的指针?

假设第一个:

 #include  int main(void) { double ***cdr = malloc(sizeof *cdr * NUM_REGIONS); if (cdr) { size_t i; for (i = 0; i < NUM_REGIONS; i++) { cdr[i] = malloc(sizeof *cdr[i] * numRatings); if (cdr[i]) { cdr[i][j] = malloc(sizeof *cdr[i][j] * remQuarters); } } } return 0; } 

有几点需要注意:

  1. 不要malloc()的返回值。 从C89开始,您不需要(void指针被隐式转换为目标指针类型),如果您忘记包含stdlib.h或者在范围内没有malloc()的原型,则转换将抑制有用的“不兼容的分配类型”诊断。
  2. 对正在分配的对象使用sizeof运算符,而不是类型表达式。 如果目标对象的类型发生变化,这可以保护您; 我认为它还有助于提高可读性。

这应该工作; 你应该有一个双倍的3D数组

 double cdr[NUM_REGIONS][numRatings][remQuarters]; 

事实certificate,编写的代码是有效的(虽然它确实有改进风格的空间,正如几个人所指出的那样)。 我在我的代码中跟踪了一些对于缓冲区来说太大的文件输入的实际问题(这对我来说是错误检查的一个教训)。

调试器提供了一些奇怪的输出,让我专注于这部分代码。 我仍然不明白为什么我的调试器在其他人不这样做时这样做,但我会在另一天处理。