Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在c语言中改变分配内存的维数_C_Memory_Malloc_Avr - Fatal编程技术网

在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
128
uint8\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,我