4

我想知道是否在 C 中声明了一个 int 元素数组。是否存在一种模式,根据该模式,只有数组的某些值被分配为 0,而其他值则存储垃圾值?前任:

#include <stdio.h>

void main()
{
    int a[5];
    int i;
    for (i=0;i<=4;i++)
    {
        printf("%d\n",a[i]);
    }
}

在我编译并运行程序后,我得到了这个输出,即

0
0
4195344
0
2107770384

因此,零在其中,a[0], a[1]并且每次编译和运行a[3]时都包含相同的值,而值不断变化(包括负数)。为什么会发生这种情况,只有数组的一些固定索引被初始化为零,并且它是否与过去的内存空间分配有关?a[2]a[4]

4

4 回答 4

8

这种行为是未定义的,它只是一个巧合。当您在堆栈上声明一个数组并且不对其进行初始化时,该数组将采用来自另一个(可能是前一个)堆栈帧的值。

旁白:如果您想对堆栈上声明的数组进行零填充(以恒定时间),则可以使用以下初始化语法对其进行初始化:

int arr[ 5 ] = { 0 };

它将第一个元素写入 0 并将其余元素填充为零。但是,如果您全局声明了一个未初始化的数组,那么它将自动被零填充。

于 2013-08-09T20:50:50.970 回答
1

在 C 中,当您以这种方式声明数组时,它不会初始化数组。这都是垃圾数据。有零是幸运的。

如果要将数组初始化为 0,请使用

memset(a,0,sizeof(a));

于 2013-08-09T20:45:09.167 回答
1

这是一种未定义的行为,它取决于操作系统。未分配数组的初始值未定义。作为一种良好做法,您有责任为它们分配一个值。

于 2013-08-09T20:45:35.147 回答
1

我只是猜你通过终端运行代码说:

首先,你跑步./a.out或你命名的其他东西。

其次,再调用termianl进程(父进程)fork()创建一个新进程(子进程)。现在子进程看起来和父进程一样,一切都是从它的父进程复制的,就像堆栈内存中的所有数据一样。

第三,子进程调用exce函数来加载你的程序。但是,新进程并没有清除所有未使用的内存,它只是保留从父进程复制的值,甚至部分父进程也没有初始化。因此,当您int a[5];在未初始化的子进程中声明时,它只是从堆栈中分配一个大小为 20 的内存,操作系统知道这些内存属于a[5],但 中的值a[5]仍然未知。它可以是每个值,也许依赖于终端进程,也许不是。

因此,如果可以的话,在声明变量时初始化变量是一个很好的习惯。

只需使用int array = {0};

于 2013-08-10T15:30:08.133 回答