我正在使用二维结构数组,这是另一个结构的一部分.这不是我做了很多事情所以我遇到了问题.在接近结束的"测试"for-loop之后,此函数最终失败.它在出现故障之前正确打印出一行.
我的代码中将数据读入虚拟2-d结构数组的部分工作正常,因此必须将我的赋值数组作为另一个结构(imageStruct)的一部分.
任何帮助将不胜感激!
/*the structure of each pixel*/
typedef struct
{
int R,G,B;
}pixelStruct;
/*data for each image*/
typedef struct
{
int height;
int width;
pixelStruct *arr; /*pointer to 2-d array of pixels*/
} imageStruct;
imageStruct ReadImage(char * filename)
{
FILE *image=fopen(filename,"r");
imageStruct thisImage;
/*get header data from image*/
/*make a 2-d array of of pixels*/
pixelStruct imageArr[thisImage.height][thisImage.width];
/*Read in the image. */
/*I know this works because I after storing the image data in the
imageArr array, I printed each element from the array to the
screen.*/
/*so now I want to take the array called imageArr and put it in the
imageStruct called thisImage*/
thisImage.arr = malloc(sizeof(imageArr));
//allocate enough space in struct for the image array.
*thisImage.arr = *imageArr; /*put imageArr into the thisImage imagestruct*/
//test to see if assignment worked: (this is where it fails)
for (i = 0; i < thisImage.height; i++)
{
for (j = 0; j < thisImage.width; j++)
{
printf("\n%d: R: %d G: %d B: %d\n", i ,thisImage.arr[i][j].R,
thisImage.arr[i][j].G, thisImage.arr[i][j].B);
}
}
return thisImage;
}
Run Code Online (Sandbox Code Playgroud)
(如果你想知道为什么我首先使用虚拟数组,那么因为当我开始编写这段代码时,我无法弄清楚如何做我现在想做的事情.)
编辑:有人建议我没有在imageStruct的typedef中正确初始化我的二维数组.如果问题确实存在,任何人都可以帮我纠正吗?
您似乎能够创建可变长度数组,因此您可以使用C99系统,也可以使用支持它的系统.但并非所有编译器都支持这些.如果要使用它们,则不需要arr
结构中的指针声明.假设没有可变长度数组,让我们看一下代码的相关部分:
/*data for each image*/
typedef struct
{
int height;
int width;
pixelStruct *arr; /*pointer to 2-d array of pixels*/
} imageStruct;
Run Code Online (Sandbox Code Playgroud)
arr
是一个指针pixelStruct
,而不是二维像素数组.当然,你可以使用arr
访问这样一个数组,但评论是误导,它暗示了一个误解.如果你真的想声明这样一个变量,你会做类似的事情:
pixelStruct (*arr)[2][3];
Run Code Online (Sandbox Code Playgroud)
并且arr
将是指向"pixelStruct的数组3的数组2"的指针,这意味着arr
指向2-d数组.这不是你想要的.公平地说,这不是你宣布的,所以一切都很好.但是你的评论暗示了对C中指针的误解,这在你的代码中会有所体现.
在这一点上,你将很好地阅读C中对数组和指针的一个很好的介绍,一个非常好的是C For Smarties:阵列和指针 Chris Torek.特别是,请确保您了解页面上的第一个图表以及该函数定义中的所有内容f
.
由于您希望能够arr
使用"column"和"row"索引以自然方式进行索引,因此我建议您将其声明arr
为指针指针.所以你的结构变成:
/* data for each image */
typedef struct
{
int height;
int width;
pixelStruct **arr; /* Image data of height*width dimensions */
} imageStruct;
Run Code Online (Sandbox Code Playgroud)
然后在你的ReadImage
函数中,你分配你需要的内存:
int i;
thisImage.arr = malloc(thisImage.height * sizeof *thisImage.arr);
for (i=0; i < thisImage.height; ++i)
thisImage.arr[i] = malloc(thisImage.width * sizeof *thisImage.arr[i]);
Run Code Online (Sandbox Code Playgroud)
请注意,为清楚起见,我没有进行任何错误检查malloc
.在实践中,您应该检查是否malloc
返回NULL
并采取适当的措施.
假设所有内存分配都成功,您现在可以读取您的图像thisImage.arr
(就像您imageArr
在原始函数中所做的那样).
一旦完成thisImage.arr
,请确保释放它:
for (i=0; i < thisImage.height; ++i)
free(thisImage.arr[i]);
free(thisImage.arr);
Run Code Online (Sandbox Code Playgroud)
实际上,您需要将上面的分配和释放部分包装在分配和释放arr
对象的各自函数中,并负责错误检查.