【问题标题】:Consistent pattern in garbage value from uninitialized array来自未初始化数组的垃圾值的一致模式
【发布时间】:2021-08-19 07:25:39
【问题描述】:

据我了解,C 中未初始化的数组意味着为数组分配的内存中的垃圾值。但是当我对此进行实验时。 所以,我尝试了这个。

#include <stdio.h>
int main (){
    int j[10];
    for(int k = 0; k < 10;k++){
        printf("j[%d]:%d\n",k,j[k]);
    }
}

这是输出:

j[0]:0
j[1]:0
j[2]:0
j[3]:0
j[4]:0
j[5]:0
j[6]:0
j[7]:0
j[8]:0
j[9]:0

我假设 clang 只是通过将默认值放入其中来修复的。我正在使用在 M1 MacBook Air 上运行的 Apple clang 版本 12.0.5 (clang-1205.0.22.11)。 现在这是令人困惑的部分:

#include <stdio.h>
int main (){
    int i =10;
    int j[i];
    for(int k = 0; k < 10;k++){
        printf("j[%d]:%d\n",k,j[k]);
    }
}

这是我得到的: 第一次运行

j[0]:13172736
j[1]:1
j[2]:13172736
j[3]:1
j[4]:0
j[5]:0
j[6]:1865774432
j[7]:1
j[8]:48
j[9]:0

第二次运行

j[0]:72499200
j[1]:1
j[2]:72499200
j[3]:1
j[4]:0
j[5]:0
j[6]:1806906720
j[7]:1
j[8]:48
j[9]:0

第三次运行。

j[0]:8912896
j[1]:1
j[2]:8912896
j[3]:1
j[4]:0
j[5]:0
j[6]:1870689632
j[7]:1
j[8]:48
j[9]:0

第四:

j[0]:15417344
j[1]:1
j[2]:15417344
j[3]:1
j[4]:0
j[5]:0
j[6]:1863988576
j[7]:1
j[8]:48
j[9]:0

这里似乎有一些规律,而且非常一致,这是从哪里来的?

【问题讨论】:

  • IIRC 在调试模式构建中,一些编译器使用一些特殊值初始化变量以明确它们未初始化。
  • 未定义的行为可以产生各种结果,包括一致的模式。 避免它。
  • “垃圾”并不意味着“随机”。它的意思是“没用”、“垃圾”或“垃圾”。它来自以前的活动,可能那个活动是一致的。
  • This is the only reference I found。引用:“未初始化的变量未设置为零;它们被初始化为特殊的填充模式,0xcc0xcd(取决于内存是在堆栈上分配还是在调试堆上分配)。”。更新:还找到this in-deep explanation
  • @UweKeim,谢谢,第二次阅读内容丰富。

标签: arrays c clang


【解决方案1】:

main 运行之前,启动代码运行。当你构建一个 C 程序时,链接器包含了 C 环境的特殊启动代码,它把程序的起始地址设置为这个代码的开头。 (此代码的地址可能用符号_startstart 表示。)当程序加载器完成将程序加载到内存中时,它会启动在该地址处运行的程序。

该代码可能会初始化堆栈区域并为printf 系列例程、malloc 例程以及 C 或您的特定操作系统的其他功能设置初始数据。在这样做时,它会使用一些堆栈空间。您看到的数据是该活动的结果。启动代码完成后,它会调用您的 main 例程。

您看到的不同数字是因为现代通用操作系统使用address space layout randomization 来阻止攻击者。结果是程序中某些事物的地址,例如代码的开头、静态数据或堆栈,因运行而异。

您不能依赖其中的数据或模式。特别是,当您在编译程序时启用优化时,编译器可能会更改数组在内存中的布局位置,或者如果它认为不需要产生 C 标准要求的结果,它可能会省略从内存中加载数据。此外,模式可能会在您的 C 编译器及其相关库的版本之间发生变化,包括启动代码,因为新版本的编译器可能会以不同的方式在内存中排列事物,并且新版本的启动代码可能会在执行它们时留下不同的数据工作。

【讨论】:

  • 所以,简而言之,来自操作系统的编译器工作+ASLR 造就了这些东西。谢谢。
猜你喜欢
  • 2015-02-28
  • 1970-01-01
  • 1970-01-01
  • 2021-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-19
  • 2014-08-16
相关资源
最近更新 更多