c -将3D数组指针重定向到2D



我试图从3D数组中获取2D子数组,并将其传递给函数。原因是要像操作2D数组的数组一样操作这个3D数组中的数据。然而,数据应该像传递二维数组一样传递给函数。

pixelval_t subFrameData[MAX_SUBFRAMES][ARRAY_WIDTH][ARRAY_HEIGHT];

我使用了一些指针魔法,它工作了,并且不显示警告。然而,在一个边缘情况下,它确实给出了一个[-Wstringop-overflow=]警告。

那么下面是有效的:

// function prototype
void SendImageBuffer_Subframe(pixelval_t dataarr[ARRAY_WIDTH][ARRAY_HEIGHT]);
...
// Some function somewhere
...
for (int i = 0; i < MAX_SUBFRAMES; i++) {
pixelval_t * ptr = &(subFrameData[i][0][0]); //get pointer of first element of 2D array
SendImageBuffer_Subframe((pixelval_t (*)[ARRAY_HEIGHT]) ptr); //cast pointer and call function
}
...

但是,如果我对固定索引而不是变量执行相同的操作:

// function prototype
void SendImageBuffer_Subframe(pixelval_t dataarr[ARRAY_WIDTH][ARRAY_HEIGHT]);
...
// Some function somewhere
...
pixelval_t * ptr = &(subFrameData[0][0][0]); //get pointer
SendImageBuffer_Subframe((pixelval_t (*)[ARRAY_HEIGHT]) ptr); //cast pointer and call function
}
...

给出如下警告:

main.c: In function ‘main’:
main.c:67:9: warning: ‘SendImageBuffer_Subframe’ accessing 48 bytes in a region of size 12 [-Wstringop-overflow=]
67 |         SendImageBuffer_Subframe((pixelval_t (*)[ARRAY_HEIGHT]) ptr);
|         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.c:67:9: note: referencing argument 1 of type ‘pixelval_t (*)[6]’ {aka ‘short int (*)[6]’}
main.c:35:6: note: in a call to function ‘SendImageBuffer_Subframe’
35 | void SendImageBuffer_Subframe(pixelval_t dataarr[ARRAY_WIDTH][ARRAY_HEIGHT]){
|      ^~~~~~~~~~~~~~~~~~~~~~~~

但是,代码确实可以工作,并且它给出了预期的输出。

在编写这些代码时,我发现下面的代码可以正常工作,没有错误

const int defaultIndex = 0;
pixelval_t * ptr = &(subFrameData[defaultIndex][0][0]);
SendImageBuffer_Subframe((pixelval_t (*)[ARRAY_HEIGHT]) ptr);

我猜结果是一样的。这只是一个编译器的怪癖,还是有一个适当的解释?还是我在重铸指针的过程中完全走错了方向?

注意:我知道我可以通过直接操作数组指针来避免所有这些问题。但是我发现数组的语法糖很好地保持了代码的可理解性。

或者我只是完全在错误的轨道上重铸指针?

是的。

原因是将3D数组中的数据当作2D数组的数组来操作。

其中一个二维数组。这就是C语言中多维数组的工作原理。my_3D_array[i]给出一个二维数组。不需要强制转换。

所以你的函数应该是:

for (int i = 0; i < MAX_SUBFRAMES; i++) {
SendImageBuffer_Subframe(subFrameData[i]); 
}

至于为什么(pixelval_t (*)[ARRAY_HEIGHT])强制转换工作,这只是因为碰巧在该内存位置上有一个1D数组。和一个二维数组。还有一个3D阵列。还有一个单品。它们都从同一个地址开始

任何带有数组的C函数都会将数组静默地调整为指向该数组第一个元素的指针。在pixelval_t dataarr[ARRAY_WIDTH][ARRAY_HEIGHT]的情况下,第一个项目的类型是pixelval_t [ARRAY_HEIGHT],指针指向pixelval_t (*) [ARRAY_HEIGHT]。因此,强制转换不会导致任何编译器消息,因为:

void SendImageBuffer_Subframe(pixelval_t dataarr[ARRAY_WIDTH][ARRAY_HEIGHT]);

100%等价于:

void SendImageBuffer_Subframe(pixelval_t (*dataarr)[ARRAY_HEIGHT]);

相关内容

  • 没有找到相关文章

最新更新