我必须使用3维数组,因为我想将pic划分为正方形并存储我阵列中每个正方形的RGB平均值。
我希望它的大小为tab[height][width][3]
,
所以我这样做了:
i = 0; j = 0; k = 0;
float*** tab;
tab = malloc((hauteur+1)*sizeof(float*));
while(i <= hauteur){
tab[i] = malloc((largeur+1)*sizeof(float**) );
i++;
}
i = 0;
while(i <= hauteur){
j = 0;
while (j <= largeur){
tab[i][j] = malloc(3*sizeof(float***));
j++;
}
i++;
}
但在tab[1][30][2];
之后我有一个段错误。
我的malloc
是否有问题?
这很奇怪,因为当我使用以下内容声明tab
时,它不会出现段错误:
tab[hauteur][largeur][3]
。
(对不起:“hauteur”在法语中表示“高度”,“largeur”表示“宽度”。)
(如果您认为需要检查我的整个功能:http://pastebin.com/eqQXz8Ad;它是JPEG文件的编写者。)
答案 0 :(得分:2)
您的malloc
来电中的类型并不正确。我建议如下:
tab = malloc( (hauteur + 1) * sizeof *tab ); // sizeof (float **)
tab[i] = malloc( (largeur + 1) * sizeof *tab[i] ); // sizeof (float *)
tab[i][j] = malloc( 3 * sizeof *tab[i][j] ); // sizeof (float)
鉴于tab
的声明,以下都是正确的:
Expression Type
---------- ----
tab float ***
*tab float **
tab[i] float **
*tab[i] float *
tab[i][j] float *
*tab[i][j] float
我通常建议使用目标表达式的sizeof
,而不是显式类型;这样,如果您更改tab
的类型(例如,从float
更改为double
),则无需触及malloc
来电。
答案 1 :(得分:1)
你正在制作的是一个浮动指针数组的数组,而不是浮点数的三维数组。 您可能需要查看此Ambiguity in 2d array declaration in C。它解决了二维数组的类似问题。
也许您问题的解决方案可能如下:
float (*tab)[hauteur][largeur][3]; //declare a pointer to a real array
tab = malloc(hauteur * largeur * 3 * sizeof(float)); //Allocate room for threedimensional array
for (int i=0; i<hauteur; i++)
for (int j=0; j<largeur; j++)
for (int k=0; k<3; k++)
{
(*tab)[i][j][k] = (float)((i*100)+j*1000+k); //Fill elements with something using threedimensional subscripting
}
for (int i=0; i<hauteur; i++)
for (int j=0; j<largeur; j++)
for (int k=0; k<3; k++)
{
printf("[%d][%d][%d]=%f\n", i, j, k, (*tab)[i][j][k]); //Check back data...
}
<强> EDITED 强>
看看评论,我发现这是不自然的&#39;使用指向数组表示法(*array)[a][b]...[n]
的指针访问数组,即使此表示法明确报告声明中的整个维度。为了使用更友好,您可以使用下面的表格,其中包含众所周知的格式:
#include <stdio.h>
#include <stdlib.h>
int largeur = 10;
int hauteur = 10;
int main(int argc, char *argv[])
{
float (*tab)[largeur][3]; //declare a bidimensional array of pointers to our variable
//this fools the compiler acting as a one more dimension array of variable
tab = malloc(hauteur * largeur * 3 * sizeof(float)); //Allocate room for threedimensional array
for (int i=0; i<hauteur; i++)
for (int j=0; j<largeur; j++)
for (int k=0; k<3; k++)
{
tab[i][j][k] = (float)((i*100)+j*1000+k); //Fill elements with something using threedimensional subscripting
//This use the natural addressing...
}
for (int i=0; i<hauteur; i++)
for (int j=0; j<largeur; j++)
for (int k=0; k<3; k++)
{
printf("[%d][%d][%d]=%f\n", i, j, k, tab[i][j][k]); //Check back data...
}
}
由于 C 语言缺乏多维数组概念,这种技巧很有效。
C只知道数组,或者更好的是它应该是 string ,所以二维数组只是一个数组的数组。如果我们再添加一个维度,它就是一个数组数组的数组......等等我们添加的每个维度。
这定义了C中数组的内存布局以及编译器用于访问数据的寻址方法。因为数据在内存中流式传输以访问特定下标的值,所以编译器需要计算用于所有维度的空间,但最先是。
+++我修复了一个错误,现在样本可以在任何符合C99-C11标准的编译器下编译并运行。
答案 2 :(得分:0)
如果你非常关心效率,你应该考虑使用单个维度数组(如Frankie_C's answer中所示):
int height = something_to_compute_height();
int width = something_to_compute_width();
double *arr = malloc(height*width*3*sizeof(double));
if (!arr) { perror("malloc"); exit(EXIT_FAILURE); }
(顺便说一句,即使我们都是母语为法语的人,我们也可以尝试在问题和代码中使用英语)
然后你可以定义一个宏来轻松说出arr
#define ELEM_ARR(a,i,j,k) a[i*width*height+j*width+k]
#define ARR(i,j,k) ELEM_ARR(arr)
(你已经明白了,细节可能会有所不同)
由于cache位置的原因,这可能比指针数组的指针数组更有效,因为你只需要一次分配。
谨慎选择row-major或专栏访问权限以适应最常用的访问模式。
如果height
&amp; width
特定于每个数组,您可以在struct
中使用一些flexible array member作为最后一个。
根据经验,只有当所有维度(可能是最后一个维度)都是编译时常量时,在C中使用多维数组才有用。 double arr3d[3][4][5];
;否则,最好有一个单维数组并自己进行索引计算。