gpt4 book ai didi

c - 为什么 memset 在 calloc 之后调用?

转载 作者:太空狗 更新时间:2023-10-29 15:17:20 25 4
gpt4 key购买 nike

我研究了一些库的代码,注意到对 calloc 的调用之后是 memset,用于由 calloc 分配的 block 。我发现这个问题对 callocmalloc + memset 和调用 memset 之间的区别有相当全面的回答就在分配存储之前:

Why malloc+memset is slower than calloc?

我仍然不明白为什么有人要这样做。这种操作有什么好处?

上述库中的代码示例:

light_pcapng_file_info *light_create_default_file_info()
{
light_pcapng_file_info *default_file_info = calloc(1, sizeof(light_pcapng_file_info));
memset(default_file_info, 0, sizeof(light_pcapng_file_info));
default_file_info->major_version = 1;
return default_file_info;
}

分配结构体代码(每个数组32个元素):

typedef struct _light_pcapng_file_info {
uint16_t major_version;
uint16_t minor_version;
char *file_comment;
size_t file_comment_size;
char *hardware_desc;
size_t hardware_desc_size;
char *os_desc;
size_t os_desc_size;
char *user_app_desc;
size_t user_app_desc_size;
size_t interface_block_count;
uint16_t link_types[MAX_SUPPORTED_INTERFACE_BLOCKS];
double timestamp_resolution[MAX_SUPPORTED_INTERFACE_BLOCKS];

} light_pcapng_file_info;

编辑:

除了已接受的答案外,我还想提供一些我同事指出的信息。 glibc 中有一个错误,有时会阻止 calloc 清零内存。这是链接: https://bugzilla.redhat.com/show_bug.cgi?id=1293976

万一链接被移动的实际错误报告文本:

glibc:calloc() 返回非零内存

问题描述:

在 Facebook,我们有一个应用程序在从 glibc-2.12-1.149.el6.x86_64 转到 glibc-2.12-1.163.el6.x86_64 时开始奇怪地挂起和崩溃。原来这个补丁

glibc-rh1066724.补丁

介绍问题。

您将以下位添加到 _int_malloc()

  /* There are no usable arenas.  Fall back to sysmalloc to get a chunk from
mmap. */
if (__glibc_unlikely (av == NULL))
{
void *p = sYSMALLOc (nb, av);
if (p != NULL)
alloc_perturb (p, bytes);
return p;
}

但这不行,alloc_perturb 无条件地 memset 的前字节到 0xf,不像上游它检查是否设置了 perturb_byte。这需要更改为

if (p != NULL && && __builtin_expect(perturb_byte, 0))
alloc_perturb (p, bytes);
return p;

我附加的补丁为我解决了这个问题。

这个问题因竞技场上的任何类型的锁争用导致我们退回到 mmap()'ing 新 block 这一事实而加剧。这是因为我们检查我们检查的无竞争竞技场是否损坏,如果是,我们循环遍历,如果我们循环到开头,我们知道我们没有找到任何东西。除非我们的初始竞技场实际上没有损坏,否则我们仍会返回 NULL,因此我们更频繁地求助于这个 mmap() 事情,这确实使事情变得不稳定。

请尽快修复此问题,我什至可以将其称为可能的安全问题。

最佳答案

调用memset() 确保操作系统实际执行虚拟内存映射。正如您链接的问题的答案中所述,可以优化 calloc() 以便延迟实际的内存映射。

应用程序可能有理由延迟虚拟内存映射的实际创建——例如使用缓冲区从非常高速的设备读取,尽管在使用memset() 将内存清零,使用 calloc() 而不是 malloc() 似乎是多余的。

关于c - 为什么 memset 在 calloc 之后调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54574920/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com