首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >malloc像calloc一样工作。

malloc像calloc一样工作。
EN

Stack Overflow用户
提问于 2020-10-19 19:35:05
回答 2查看 147关注 0票数 0

当malloc运行时,它生成内存块,它不设置任何值,并且包含垃圾值。在calloc运行时,会发生一些类似malloc函数的事件,但有一个不同之处。当calloc生成新块时,它会在块中设置0(Zero)。

代码语言:javascript
运行
复制
#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标准,但结果并没有不同。我要问的是什么原因。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-10-20 09:43:58

malloc的行为是,它返回未初始化的内存。从未初始化的内存读取是未定义的行为,这意味着任何事情都可能发生;而一个足够聪明的编译器检测到,您正在从未初始化的内存读取,甚至可能优化读取并替换为常量值,甚至终止您的程序。

也就是说,您读取的是零,而不是存储在内存中的任何部分的剩馀值,这是出于安全考虑。几年前,它的行为实际上是这样的。但后来人们意识到,这可能会泄露密钥或其他秘密,从而改变了Linux‘(和*BSD)内核的行为,以便在第一次将内存页映射到进程时将其归零。对于Linux,这种行为是在Linux-2.6.33中引入的。赛瑟尔 ( malloc/calloc分配程序内部用于与内核对话的内容)获得了一个新标志:

MAP_UNINITIALIZED (自从Linux2.6.33之后) 不要清除匿名页面。此标志旨在提高嵌入式设备的性能。只有当内核配置了CONFIG_MMAP_ALLOW_UNINITIALIZED选项时,才会使用此标志。由于安全问题,该选项通常只在嵌入式设备(即对用户内存内容有完全控制的设备)上启用。

票数 2
EN

Stack Overflow用户

发布于 2020-10-19 19:46:30

malloc不使用零填充数据(正如您预期的那样)。但不能保证垃圾数据不是零。所以,如果您分配内存,并看到所有字段有时或在某些情况下为零,这是可以的。我假设您将看到“更多的随机”数据在“错位”内存中,如果大小要大得多,或者如果您要分配,填充smth,空闲,再分配。但是使用calloc,即使在这样的操作之后,您仍然会看到零内存。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64434057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档