当我使用'malloc()'时,为什么数据模式出现在内存中?
我有一个简单的代码:当我使用'malloc()'时,为什么数据模式出现在内存中?,c,memory,malloc,C,Memory,Malloc,我有一个简单的代码: #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]); ret
#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;
}
#包括
#包括
内部主(空){
char*str=(char*)malloc(4*sizeof(char));
int i;
对于(i=0;i<64;i++)
printf(“%d,%ld,%d,%c\n”,i,(long)和(str[i]),(int)str[i],str[i]);
返回0;
}
我使用malloc()
将内存分配到str
中,该内存可用于在str[0]、…、str[3]
中保存4个字母。我知道malloc()
此程序按顺序打印str[i]
、地址str[i]
、值str[i]
、字母str[i]
。(我使用64位Ubuntu,因此地址是long
type。)
正如预期的那样,每次运行程序时,地址都是完全不同的。但我想知道为什么str[24]
、str[25]
和str[26]
分别是-31、15、2,而其他值都是0,如下所示:
(请注意,如果没有选项-O0,则会得到相同的结果。)
内存怎么会有相同的序列(0,0,…,0,-31,15,2,0,0,…),即使只分配了该序列中的前四个0,而其他0则不小心?正如您刚才指出的,malloc()
不会初始化内存(顺便说一句,即使它会从str[4*sizeof(char)]
它不会被初始化,因为它已经超出范围)
这意味着您可以打印出以前在此内存位置的数据。这是完全不可预测的未定义行为
事实上,您看到的是相同的值,这可能是巧合。但若可以重复,并且总是使用相同的值,它很可能会跟踪操作系统和标准库在将控制权交给main()
之前初始化进程环境所做的工作
堆栈上有一个关于未初始化变量的问题。单元化数据访问剩余值的原理与此类似,只是它位于堆上
下面是一个实验:一个小程序,试图向您展示可能发生的事情(注意:这取决于实现):
intmain(){
int i;
//第一部分================
char*p=(char*)malloc(100);//在内存中分配一个区域
因为(i=0;我知道,str[24:26]
和str[4:63]
远远超出了您分配的正确范围?因此您表现出未定义的行为?@BillLynch我当然知道。但每当我运行程序时,str[24:26]总是有-31,15,2。我认为这种现象非常不正常,因为这些str[24:26]超出了您指出的范围。malloc
可能会从操作系统获得比您实际要求的更多的内存,以提高其自身的效率。您尚未初始化正在查看的内存,因此它可能包含任何内容。我怀疑您看到的是malloc()的另一段内存的标头更早分配。可能在main()之前
。但是每次,地址都会改变。如图所示,str
是7598096,因此-31存储在7598120。我刚才重新运行了该程序,str
是25088016,-31存储在25088040。如果操作系统每次都给出相同的内存块,那么为什么它们有不同的地址?@Analysis是:初始化on sequence是在进程的地址空间中运行的。因此,如果它在内存中留下其活动的痕迹,则它们的位置可能与进程的起始地址空间的起始位置相比。@Analysis:我编辑了一些代码,试图向您展示这种现象。
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;
}