当malloc运行时,它生成内存块,它不设置任何值,并且包含垃圾值。在calloc运行时,会发生一些类似malloc函数的事件,但有一个不同之处。当calloc生成新块时,它会在块中设置0(Zero)。
#include <stdio.h>
#include <stdlib.h>
int main(void){
int i,j;
int* array1 = (int*)malloc(sizeof(int)*5);
int* array2 = (int*)calloc(sizeof(int),5);
for(i = 0; i < 5; i++){
printf("%p: %d\n",&array1[i],array1[i]);
}
printf("===================\n");
for(j = 0; j < 5; j++){
printf("%p: %d\n",&array2[j],array2[j]);
}
return 0;
}
根据这些信息,前五个值必须包含垃圾值(实际上它应该看起来像随机数据),第二个值必须是零。然而,当这段代码在Windows中运行时,没有问题,但是当这段代码在Linux中运行时,这种情况就不会发生了。我认为它依赖于ASLR或DEP保护,我关闭了ASLR,我使用旧的Linux系统进行DEP保护,但结果是一样的。最后,我认为它可能依赖于C标准,我在编译代码时更改了C标准,但结果并没有不同。我要问的是什么原因。
发布于 2020-10-20 01:43:58
malloc
的行为是,它返回未初始化的内存。从未初始化的内存读取是未定义的行为,这意味着任何事情都可能发生;而一个足够聪明的编译器检测到,您正在从未初始化的内存读取,甚至可能优化读取并替换为常量值,甚至终止您的程序。
也就是说,您读取的是零,而不是存储在内存中的任何部分的剩馀值,这是出于安全考虑。几年前,它的行为实际上是这样的。但后来人们意识到,这可能会泄露密钥或其他秘密,从而改变了Linux‘(和*BSD)内核的行为,以便在第一次将内存页映射到进程时将其归零。对于Linux,这种行为是在Linux-2.6.33中引入的。赛瑟尔 ( malloc/calloc分配程序内部用于与内核对话的内容)获得了一个新标志:
MAP_UNINITIALIZED (自从Linux2.6.33之后) 不要清除匿名页面。此标志旨在提高嵌入式设备的性能。只有当内核配置了CONFIG_MMAP_ALLOW_UNINITIALIZED选项时,才会使用此标志。由于安全问题,该选项通常只在嵌入式设备(即对用户内存内容有完全控制的设备)上启用。
发布于 2020-10-19 11:46:30
malloc
不使用零填充数据(正如您预期的那样)。但不能保证垃圾数据不是零。所以,如果您分配内存,并看到所有字段有时或在某些情况下为零,这是可以的。我假设您将看到“更多的随机”数据在“错位”内存中,如果大小要大得多,或者如果您要分配,填充smth,空闲,再分配。但是使用calloc
,即使在这样的操作之后,您仍然会看到零内存。
https://stackoverflow.com/questions/64434057
复制相似问题