我今天刚在类考试---阅读C代码和输入,要求的答案是程序实际运行时屏幕上会出现什么。申报问题之一a[4][4]
作为全局变量并在该程序的某个点,它尝试访问 a[27][27]
,所以我回答了类似“Accessing an array outside its bounds is an undefined behavior”的问题,但老师说的是a[27][27]
的值为 0
.
后来,我尝试了some code检查“所有未初始化的 golbal 变量都设置为 0
”是否为真。好吧,这似乎是真的。
那么现在我的问题是:
- 似乎一些额外的内存已被清除并保留用于代码运行。保留多少内存?为什么编译器会保留比应有的更多的内存,它有什么用?
- 威尔
a[27][27]
是0
适用于所有环境?
编辑:
在该代码中,a[4][4]
是声明的唯一 全局变量,main()
中还有一些局部变量.
我试过了 that code再次在 DevC++ 中。都是0
.但在 VSE 中情况并非如此,其中大多数值是 0
但正如 Vyktor 指出的那样,有些具有随机值。
最佳答案
你是对的:这是未定义的行为,你不能指望它总是产生 0
。
至于为什么在这种情况下您会看到零:现代操作系统以相对粗粒度的 block (称为页面)为进程分配内存,这些 block 比单个变量大得多(在 x86 上至少为 4KB)。当您只有一个全局变量时,它将位于页面的某个位置。假设 a
的类型为 int[][]
并且 int
在您的系统上是四个字节,a[27][27 ]
将位于 a
开头约 500 字节处。所以只要 a
靠近页面的开头,访问 a[27][27]
就会得到实际内存的支持,读取它不会导致页面故障/访问冲突。
当然,你不能指望这个。例如,如果 a
前面有将近 4KB 的其他全局变量,那么 a[27][27]
将不会得到内存支持,当您执行以下操作时,您的进程将崩溃尝试阅读它。
即使进程没有崩溃,您也不能指望得到值 0
。如果您在现代多用户操作系统上有一个非常简单的程序,除了分配这个变量并打印那个值之外什么都不做,您可能会看到 0
。操作系统在将内存移交给进程时将内存内容设置为某个良性值(通常全为零),以便来自一个进程或用户的敏感数据不会泄漏到另一个。
但是,并不能保证您读取的任意内存将为零。您可以在内存未在分配时初始化的平台上运行您的程序,并且您会看到上次使用时碰巧存在的任何值。
此外,如果 a
后跟足够多的其他初始化为非零值的全局变量,那么访问 a[27][27]
将显示任何值恰好在那里。
关于c - 是否在其绑定(bind)的未定义行为之外访问全局数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26426910/