改变c中分配内存的维数

changing dimensionality of allocated memory in c

考虑定义如下的帧缓冲区数组:

static uint8_t framebuffer[num_buffers][1024];

数组被定义为每个显示缓冲区只有一个维度,因为底层硬件外围设备在我的嵌入式应用程序中需要它。然而,在代码的其他区域,通过额外的维度来处理相同的帧缓冲区将非常有利,例如:

framebuffer[buf][page][col];

我该如何做到这一点?使用实数,我希望 page 的范围为 0 到 7,col 为 0 到 127。注意:每页为 128 字节。例如,此语句的计算结果为真,因为它们将引用相同的字节:

framebuffer[0][130] == framebuffer[0][1][2]

因为 130 / 128 = 1(页面)和 130 % 128 = 2(列)。我假设我需要使用 malloc,但我未能产生正确的行为。

与其通过不同类型的数组访问数组,我强烈建议创建一个函数来 return 数组的正确元素。

uint8_t getFrameBufferItem(uint8_t framebuffer[][1024],
                           int i,
                           int j,
                           int k)
{
   return framebuffer[i][j*128+k];
}

创建一个类似的函数来设置项目的值。

void setFrameBufferItem(uint8_t framebuffer[][1024],
                        int i,
                        int j,
                        int k,
                        uint8_t val)
{
   framebuffer[i][j*128+k] = val;
}

你有几个选择。第一种是创建一个变量,该变量是 uint8_t 指针的双精度数组并执行以下操作:

static uint8_t original_framebuffer[num_buffers][1024];
static uint8_t *new_framebuffer[num_buffers][8];
int i;
for(i = 0; i < 8; i++) {
  new_framebuffer[0][i] = &original_framebuffer[0][i * 128];
}

这样original_framebuffer[0][130]指的是与new_framebuffer[0][1][2]

相同的内存位置

我建议的另一个选项并不完全是您想要的,但您可以将索引包装在宏中:

#define XY_ACCESS(_x, _y) ((_x) * 128 + (_y))

那么你会得到以下内容:

framebuffer[0][130] == framebuffer[0][XY_ACCESS(1, 2)]

您当然也可以使用函数而不是宏。

"dimensionality"不是分配内存的属性,而是数据类型。您可以通过具有不同维度的不同类型的指针访问同一内存,前提是您要注意确保整体大小和对齐方式兼容。因此,对于您的示例,您可以这样做:

static uint8_t framebuffer[numbuffers][1024];

uint8_t (*redimensioned)[8][128] = (uint8_t (*)[8][128])framebuffer;

.. 然后,例如,将第二个缓冲区的第 3 页的第 4 列归零为:

redimensioned[1][2][3] = 0;

详细说明一下,原始声明 uint8_t framebuffer[numbuffers][1024]; 声明了一个数组数组(numbuffers1024 uint8_t 的数组)。它会衰减为指向 1024 uint8_t 的数组的指针(或 uint8_t (*)[1024],也可以作为 N x 1024 二维数组访问。

我们还可以通过指向 128 uint8_t8 数组的数组的指针访问原始数组的内容,这就是 uint8_t (*redimensioned)[8][128]; 给我们的,我们可以将其作为 N x 8 x 128 3 维数组访问(在将其指向原始数组的内容后)。

为了让编译器满意,当我们将 redimensioned 指向 framebuffer 的内容时,我们必须强制转换它,因为指针 framebuffer 衰减到的类型不同于我们声明的指针的类型...这是 (uint8_t (*)[8][128]) 在赋值中的来源(它是对 "pointer to arrays of 8 arrays of 128 uint8_t's" 的转换)。