arrays - 在块范围内被覆盖的未初始化数组的值
问题描述
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[]) {
int send_buf[4];
if(1){
int hello[5]={1,2,3,4,5};
}
for(int i=0; i<4; ++i)
printf("%d ",send_buf[i]);
printf("\n");
return 0;
}
输出: 1 2 3 4
在执行上述 C 代码时,输出总是导致分配给hello
块范围内的数组的值。send_buf
但是,如果在打印 array 之前进行了任何引用(例如打印 的地址) send_buf
,则输出会导致通常的不确定值。
有人可以解释为什么当内存已经在堆栈上分配send_buf
时被覆盖的值?send_buf
是否是某种 GCC 编译器优化延迟分配未初始化的数组直到它被引用?
使用 GCC 版本 9.3.0 编译。
解决方案
当您不在 C 中(显式或隐式)初始化对象时,C 标准不保证它们具有任何固定值。它们的值可能会受到任何其他情况的影响,甚至可能会因每次使用而有所不同。
由于您没有初始化数组,编译器可能允许任何其他操作影响它。这可能包括允许 的定义hello
影响出现在 中的值send_buf
。可能起作用的一个事实是编译器会对值进行生命周期分析。例如,在如下代码中:
int p;
int q = 4;
printf("%d\n", q);
p = 3;
printf("%d\n", p);
编译器可能会看到,即使p
在之前定义过q
,也永远不会有一个“活”值与p
中的值同时存在q
,因此编译器可以使用与 相同的q
内存p
。类似地,编译器可能已经决定send_buf
永远不会同时包含实时值hello
,因此它可以使用与它相同的hello
内存send_buf
。然后,由于您从未将值放入 中send_buf
,因此从中获取内存中的数据是hello
您的程序的一种可能行为。
要吸取的一个教训是,在各种情况下出现在数组中的“奇怪”值是它可能没有被初始化的线索,补救方法是初始化它。
推荐阅读
- android - billingClient.startConnection 不起作用
- angular - 更新订阅而不实时更新firestore
- python - 将多标签图像从云端硬盘上传到 Google Colab
- android - Android Exoplayer 中的 PlayerView 和 StyledPlayerView 有什么区别
- javascript - Angular Universal 会在短时间内加载登录页面
- sockets - 收听传入的whatsapp消息
- sql - SQL Server 代理作业运行成功但不输出数据
- java - 给变量赋值
- javascript - 我使用 JS 制作了秒表,但它不起作用
- python-3.x - Nginx 无法使用在 AWS EC2 实例上运行的 Flask 应用程序从登录重定向到主页