【问题标题】:Structure and array declaration on same memory location同一内存位置上的结构和数组声明
【发布时间】:2016-02-22 14:55:23
【问题描述】:

我正在开发一个嵌入式 C 项目。我无法理解代码中数组和结构的使用。

例如:

结构:

struct example_struct{
 char a;
 char b;
 char array[4];

}  

注意:Int 和 char 的默认大小为 1 字节。

我使用的编译器使用'@'符号为变量和其他参数提供内存分配功能

例如:

内存分配

int example @ 0x125
// Compiler allocate the RAM memory location 0x125 to my variable "example"  

问题:

编写这个项目的人使用了下面给出的结构和数组

example.h

struct example_struct{
char a;
char b;
char array[4];
}  

Memory.h

volatile struct example_struct node @ 0x130 ;
//allocate memory location 0x130 - 0x135 to node  
volatile char buffer[6] @ 0x130;
//allocate memory location 0x130 - 0x135 to buffer 

问题

1.不使用指针来访问结构的成员,使用放置在同一内存位置的数组是否合适?

  1. 是否会导致内存问题?

能否请您帮助我了解在这种特殊情况下使用 stuct 和 array 。

谢谢

库纳尔

【问题讨论】:

  • 这与friend/union 非常相似——至少在我看来是这样。顺便说一句 - 非常方便的助记符,可以选择在哪里初始化值。
  • "会不会导致内存问题?" -- 真正的问题是什么?
  • 可用内存为 367 字节,与此模式类似,我的代码中使用了三种不同的结构。 (每个 32 字节)
  • 如果我声明任何全局变量并使用调试器观察它,我可以看到值的变化。即使我没有在任何地方使用它们。
  • 我不明白那个评论——另外,你能否详细说明一下地址 0x130 是否有特殊意义——它是硬件地址还是某种 IO 控制器?

标签: c arrays memory struct


【解决方案1】:

开发该代码的(奇怪的)编码人员正在“模拟”union,以便能够根据byte 访问与struct example_structbyte 相同的位置。

喜欢:

#pragma pack(1)
union struct_and_raw_byte_access
{
   struct example_struct
   {
      char a;
      char b;
      char array[4];
   }structured;
   char buffer[sizeof(struct example_struct)];
};
#pragma pack()

int main(void)
{
    union struct_ad_raw_byte_access temp;
    int i;

    temp.structured.a = 1;
    temp.structured.b = 2;
    temp.structured.array[0] = 3;
    temp.structured.array[1] = 4;
    temp.structured.array[2] = 5;
    temp.structured.array[3] = 6;

    for (i=0; i< sizeof(temp.buffer)/sizeof(temp.buffer[0]); i++)
        printf("buffer[%d] = %d\n", i, temp.buffer[i]);

    return 0;
}

【讨论】:

  • Unions 不保证任何特定的字节打包,因此不会有任何区别。
  • @Soren 我没听懂你。你能详细说明一下吗?
  • 你没有做任何事情来适应填充——编译器被允许在联合的strctured部分的abarray之间添加填充字节- 因为它很可能(猜测)OP 在地址 0x130 处具有结构,因为它是某些硬件的 IO 地址 - 那么 strct 的确切大小很重要 - 即它必须是 6 个字节
  • @Soren 这正是我写#pragma pack(1) 的原因,以确保1 字节填充。
【解决方案2】:

1.不使用指针来访问结构的成员,使用放置在同一内存位置的数组是否合适?

2.会不会导致内存问题?

恕我直言,你不能这样做。它可能适用于某些拱门,但请记住,您相信编译器会将所有内容打包并对齐。

一些编译器有打包指令(pragma 或 parameteres),但使用联合更安全。

【讨论】:

    【解决方案3】:

    确保缓冲区也是一个指针,因此将“缓冲区”分配给绝对地址与创建指向该地址的指针相同。

    volatile char buffer[6] @ 0x130;
    //allocate memory location 0x130 - 0x135 to buffer 
    

    在您的情况下,开发人员;我认为;他决定使用数组访问 strcutre 元素,以便在循环或其他方式中使用它们。 所以,回答你的问题:

    1. 不,这不合适,正如你所说,最好通过将其转换为(char *)来制作指针并访问该指针
    2. 如果您知道如何使用“缓冲区”,就不会发生内存问题。我的意思是确保不会发生超出索引的情况。

    【讨论】:

      【解决方案4】:

      您的评论“如果我声明任何全局变量并使用调试器观察它,我可以看到值的变化。即使我没有在任何地方使用它们”可能意味着您正在查看一些 IO 控制器的硬件寄存器。

      volatile char buffer[6] @ 0x130;
      

      旨在将这些 IO 控制器地址映射到嵌入式编程中的变量名称。也就是说,IO 控制器在内存地址 0x130 到 0x135 处呈现状态和数据——C 程序通过声明将其映射到符号值。

      由于这个区域的格式是由 IO 控制器决定的(你在 C 代码中做的任何事情都不会改变格式),你需要确保 strct 和 example_struct 正好是 6 个字节长,或者如果不是,您有一些填充物会杀死您。

      使用您的调试器对此进行测试(如果是 gdb 使用可以使用 sizeof,但您的调试器可能会有所不同)

      另外,我建议您查找有关硬件地址 0x130 上的内容的某种文档

      【讨论】:

      • 我指定的内存位置是我的控制器的数据内存。该内存位于 0x000h - 0x01ff h 之间。当我定义任何全局变量时,编译器会在这个范围之间分配数据内存。由于这些不是 IO 寄存器,因此任何变量的值都不应改变,除非被任何函数或部分代码更新。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-14
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多