c语言 - 使用字符串时无法复制 malloc 不初始化内存的示例



为了更好地理解malloccalloc之间的差异,我试图找到一个例子,其中malloc离开内存未初始化/从以前的分配中重用它。

我遇到了SO问题,为什么malloc在gcc中将值初始化为0 ?

我试图复制这个例子,但分配了一个字符数组并设置了一个值。然而,似乎malloc在这种情况下工作,但为什么?

代码:

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main(void) {
    // this shows, that malloc does not initialize memory
    {
        double *a = malloc(sizeof(double)*100);
        *a = 100;
        printf("%fn", *a);
        free(a);
    }
    {
        double *a = malloc(sizeof(double)*100);
        printf("%fn", *a);
        free(a);
    }
    // tried the same with chars, but my example doesn't work
    {
        char *ptr = malloc(sizeof(char) * 10);
        ptr[0] = 'a';
        printf("%sn", ptr);
        free(ptr);
    }
    {
        char *ptr = malloc(sizeof(char) * 10);
        printf("%sn", ptr);
        free(ptr);
    }
    return 0;
}
输出:

$ clang -ggdb memset_test.c
$  ./a.out
100.000000
100.000000
a
<empty string>

我看不出有什么区别,为什么第一个使用double的exable可以工作,而我的却不行?

这取决于操作系统(正如@Basile Starynkevit在评论中更清楚地指出的具体实现)。malloc不会像你知道的那样将其归零,但操作系统可以这样做(这显然取决于操作系统)。

在我的系统上,我得到的输出是-

 100.000000
 0.000000
 a
 02T               // excat output that I get on my system

但是很明显,我们访问的是未初始化的内存。所以,UB。所以我们不能期望任何想要的输出

尝试为双精度对象分配与第一个malloc相同的内存量:

char *ptr = malloc(sizeof(char) * 800);

在glibc的malloc实现中,小内存块与大内存块的处理方式不同,您应该打印出返回的指针的值,以查看它们是相同的内存块。

free,它可能会覆盖以前的数据用于内部记账(空闲内存块列表)。

在每种情况下,在第二次malloc()调用后对指针解引用的行为是未定义的。

未定义行为的核心定义(是的,标准确实说明了"未定义"的含义,尽管这看起来很讽刺)是允许发生任何事情。这可以包括看起来像你期望的那样工作,在一种情况下你期望的那样工作,而不是在另一种情况下,等等。

你可能会看到不一致的行为的原因(两个类似的例子,但只有一个像预期的那样工作)通常归结为编译器如何在内存中组织数据,标准库实现如何在内存中组织数据,操作系统如何管理内存(因此malloc()返回最后一个free() d指针的可能性有多大),主机上有多少物理内存可用,等等。这些东西都是相互作用的,没有任何保证。

相关内容

  • 没有找到相关文章

最新更新