我有一个简单的代码:
#include <stdio.h>
#include <stdlib.h>
int main(void){
char *str = (char *) malloc(4*sizeof(char));
int i;
for(i = 0; i < 64; i ++)
printf("%d, %ld, %d, %c\n", i, (long) &(str[i]), (int) str[i], str[i]);
return 0;
}
我使用str
将内存分配到malloc()
,可以在str[0], ..., str[3]
中保存4个字母。我知道malloc()
在calloc()
执行时不会初始化其内存。
此程序按顺序打印str[i]
i
,地址str[i]
,价值str[i]
,str[i]
。 (我使用64位Ubuntu,因此地址为long
类型。)
正如所料,每次运行程序时地址都大不相同。但我想知道为什么str[24]
,str[25]
和str[26]
分别是-31,15,2,其他值都是0,如下所示:
(注意,没有选项-O0会得到相同的结果。)
内存如何具有相同的序列(0,0,...,0,-31,15,2,0,0,...),即使该序列中只有前四个0被分配而另一些已经被分配出来护理?
答案 0 :(得分:0)
正如您刚才所指出的那样,malloc()
没有初始化内存(顺便说一句,,即使它会从str[4*sizeof(char)]
开始,因为它已经出来了,所以它不会被初始化范围)。
这意味着您之前打印出此内存位置的数据。它是未定义的行为,因此严格无法预测。
你看到相同价值的事实可能是巧合。但是,如果可重复且始终具有相同的值,则很可能是在控制main()
之前,操作系统和标准库在初始化过程环境方面所做的工作的痕迹。
堆栈上有关于未初始化变量的related SO question。提供对剩余值的访问的单一化数据的原理在这里类似,只是它在堆上。
这是一个实验:一个小程序,试图向您展示可能发生的事情(注意:它依赖于实现):
int main() {
int i;
// first part ================
char *p=(char*)malloc(100); // allocate a region in memory
for (i=0; i<100; i++) // initialize it to 0
p[i]=0;
strcpy (p+10, "Christophe"); // put some value womewhere in the middle
free(p); // release memory
// second part ============
char *q= (char*)malloc(100); // innocently allocate new memory
// and display its content
printf ("%ld==%ld ? %c%c%c\n", (long) p, (long)q, q[10],q[11], q[12]);
return 0;
}
所以你可以想象这个代码的第一部分可以在标准库的初始化序列中运行(可能是在程序启动时,或者第一次调用malloc()
时)。
此代码的a live demo。