【问题标题】:Why does struct memory initalize with random characters? (Embedded)为什么 struct memory 用随机字符初始化? (嵌入式)
【发布时间】:2019-11-18 16:32:01
【问题描述】:

将 MCUXpresso 与 NXP MKL02Z16VFM4 一起使用以供参考。

当我这样声明一个结构时

typedef struct {
        uint8_t DATA :8;
} myStruct;
myStruct xxx __attribute__ ((section ("xyz")));

内存中的位置被随机字符填充。处理器是小端的,所以当我尝试访问这个地址时,我会得到那些随机字符和我写入结构的数据。

//At address 0x1FFFFE84 : BD84D1E4

xxx.DATA = 0xAA; //Assign some numbers to struct

//Now, 0x1FFFFE84 : BD84D1AA

我可以使用memset来清除内存,但是我想知道为什么在声明一个结构体的时候,内存会被这些随机字符填满。

【问题讨论】:

  • C 标准中没有任何内容需要初始化内存,程序员负责。
  • 地址0x1FFFFE84有什么意义?那一定不是xxx.DATA的地址。
  • 如果您陈述了您的期望和原因,会更容易回答您的问题。目前尚不清楚您需要向您解释什么 - 您引用了一个案例,该案例完全符合人们的期望,但不清楚您想要解释什么。
  • @yano : 没有初始化器的静态存储类的数据需要进行零初始化。鉴于__attribute__,这似乎是一个全局声明,因此是静态的。或许这就是“惊喜”的来源?部分分配将破坏零初始化。
  • @Clifford 啊,是的,这是有道理的,可能是。

标签: c memory embedded nxp-microcontroller


【解决方案1】:

您已在 xyz 部分中明确定位 xxx - 该部分对于编译器和默认启动代码是未知的,因此不需要像默认的 bss 段那样显式地初始化为零。对于大多数易失性内存技术,内存在上电时具有不确定的内容 - 因此在这种情况下显然是随机的。

如果您希望私有部分的初始化为零,则需要在链接描述文件和/或启动代码中明确添加。然而,结构体周围未使用内存的内容或其中的任何对齐填充是无关紧要的,并且在很大程度上没有必要明确地将其清除为某个已知值。

【讨论】:

    【解决方案2】:

    结构变量,但实际上是 ANY 变量,需要在代码中使用之前进行初始化。访问(读取)未初始化的数据会导致未定义的行为,这意味着无法保证编译器将以可预测的方式运行。

    大多数编译器设置为 0 未初始化变量,但其他一些编译器(例如,一些嵌入式编译器)没有。这就是为什么您会看到随机值。

    【讨论】:

    • 我试过用零初始化myStruct xxx __attribute__ ((section ("xyz"))) = {0}; 但这似乎没有任何效果。不过,我想我理解随机值背后的原因,谢谢。
    • 随机值是噪声或之前使用的 RAM。您可能希望遍历已分配的字节并将它们中的每一个设置为零。我不熟悉这里使用的系统,但在 c 库中我通常使用 memset(&xxx, 0, sizeof(myStruct))
    • 听起来很奇怪:myStruct xxx = {0}; 据我所知,即使没有 section 属性,也应该将你的结构初始化为 0(但我不得不说我不知道​​你的 uC)。是全局变量吗?
    • @555 :默认情况下,运行时启动初始化 BSS 和 DATA 段 - 您的对象位于 xyz 中,因此将忽略零或显式初始化,除非您将启动代码修改为处理您的自定义部分。
    • 只有 BSS 部分通常会被零初始化 - 此数据不在 BSS 中。它与省略零初始化的“嵌入式编译器”无关(在任何情况下通常都不正确 - 只是有时)。
    猜你喜欢
    • 1970-01-01
    • 2016-02-28
    • 2014-06-22
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多