在c语言中改变分配内存的维数
考虑定义如下的帧缓冲区数组:在c语言中改变分配内存的维数,c,memory,malloc,avr,C,Memory,Malloc,Avr,考虑定义如下的帧缓冲区数组: static uint8_t帧缓冲区[num_buffers][1024] 阵列被定义为每个显示缓冲区有一个维度,因为底层硬件外围设备在我的嵌入式应用程序中需要它。但是,在代码的其他区域,通过附加维度来处理相同的帧缓冲区将非常有利,例如: 帧缓冲区[buf][page][col] 我如何做到这一点?使用实数,我希望页的范围是0到7,列的范围是0到127。注:每页为128字节。例如,此语句的计算结果将为true,因为它们将引用相同的字节: framebuffer[0]
static uint8_t帧缓冲区[num_buffers][1024]代码>
阵列被定义为每个显示缓冲区有一个维度,因为底层硬件外围设备在我的嵌入式应用程序中需要它。但是,在代码的其他区域,通过附加维度来处理相同的帧缓冲区将非常有利,例如:
帧缓冲区[buf][page][col]代码>
我如何做到这一点?使用实数,我希望页的范围是0到7,列的范围是0到127。注:每页为128字节。例如,此语句的计算结果将为true,因为它们将引用相同的字节:
framebuffer[0][130]==framebuffer[0][1][2]
因为130/128=1(第页)和130%128=2(第列)。我假设我需要使用malloc,但是我在生成正确的行为方面失败了。我强烈建议创建一个函数来返回数组的正确元素,而不是通过不同类型的数组访问数组
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 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];
}
framebuffer[0][130] == framebuffer[0][XY_ACCESS(1, 2)]
那么您将拥有以下内容:
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];
}
framebuffer[0][130] == framebuffer[0][XY_ACCESS(1, 2)]
当然,您也可以使用函数而不是宏。您有两个选项。第一种方法是创建一个变量,该变量是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];
}
framebuffer[0][130] == framebuffer[0][XY_ACCESS(1, 2)]
那么您将拥有以下内容:
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];
}
framebuffer[0][130] == framebuffer[0][XY_ACCESS(1, 2)]
当然,您也可以使用函数而不是宏。维度不是分配内存的属性,而是数据类型。您可以通过不同类型、不同尺寸的指针访问同一内存,前提是要确保总体大小和对齐方式兼容。例如,您可以:
static uint8_t framebuffer[numbuffers][1024];
uint8_t (*redimensioned)[8][128] = (uint8_t (*)[8][128])framebuffer;
..然后,例如,将第2个缓冲区第3页的第4列归零:
redimensioned[1][2][3] = 0;
更详细地说,原始声明uint8_t framebuffer[numbuffers][1024]
声明数组的数组(numbuffers
1024的数组)。它将衰减为指向1024
uint8\u t
数组的指针(或uint8\u t(*)[1024]
,也可以作为nx1024
二维数组访问
我们还可以通过指向8
128
uint8\u t
数组的指针访问原始数组的内容,这是uint8\u t(*redimensed)[8][128];
给我们的,我们可以作为nx8x128
三维数组访问(在指向原始数组的内容后)
为了让编译器满意,当我们将redimmensioned
指向framebuffer
的内容时,我们必须强制转换它,因为framebuffer
指针的类型与我们声明的指针的类型不同……这就是(uint8_t(*)[8][128])
在赋值中的来源(这是对“指向128个uint8的8个数组的指针”的转换)。维度不是已分配内存的属性,而是数据类型。您可以通过具有不同维度的不同类型的指针访问同一内存,前提是您注意确保总体大小和对齐方式兼容。因此,对于您的示例,您可以执行以下操作:
static uint8_t framebuffer[numbuffers][1024];
uint8_t (*redimensioned)[8][128] = (uint8_t (*)[8][128])framebuffer;
..然后,例如,将第2个缓冲区第3页的第4列归零:
redimensioned[1][2][3] = 0;
更详细地说,原始声明
uint8\u t framebuffer[numbuffers][1024];
声明了一个数组(numbuffers
数组的1024
uint8\u t
),它将退化为指向数组的指针,也可以作为二维数组访问
我们还可以通过指向8
128uint8\u t
数组的指针访问原始数组的内容,这是uint8\u t(*redimensed)[8][128];
给我们的,我们可以作为nx8x128
三维数组访问(在指向原始数组的内容后)
为了让编译器满意,当我们将
redimmensioned
指向framebuffer
的内容时,我们必须强制转换它,因为framebuffer
指针的类型与我们声明的指针的类型不同……这就是(uint8_t(*)[8][128])
在赋值中的来源(这是对“指向128个uint8的8个数组的指针”的转换).我现在意识到我没有提到需要写入帧缓冲区,而不仅仅是从中读取。这样可以读取特定字节,但我也需要更新它们。@R Sahu感谢更新。我不记得具体是如何工作的,但我猜是帧缓冲区[][1024]
实际上是一个参考。调用函数的开销会不会比esm的第一个答案慢一些?@Anthony,这会比转换数组慢一些。我不知道有多少。我现在意识到我没有提到帧缓冲区需要写入,而不仅仅是读取。这可以读取特定字节,但我也需要d也要更新它们。@R Sahu感谢您的更新。我不记得它是如何工作的,但我猜framebuffer[][1024]
实际上是一个参考。调用函数的开销会不会比esm的第一个答案慢?@Anthony,我