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

时间:2015-09-26 06:03:58

标签: c malloc

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

我遇到了问题Why does malloc initialize the values to 0 in gcc?

我试图复制示例,但是分配一个char数组并设置一个值。但是,似乎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("%f\n", *a);
        free(a);
    }
    {
        double *a = malloc(sizeof(double)*100);
        printf("%f\n", *a);
        free(a);
    }

    // tried the same with chars, but my example doesn't work
    {
        char *ptr = malloc(sizeof(char) * 10);
        ptr[0] = 'a';
        printf("%s\n", ptr);
        free(ptr);
    }

    {
        char *ptr = malloc(sizeof(char) * 10);
        printf("%s\n", ptr);
        free(ptr);
    }

    return 0;
}

输出:

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

我看不出差异,为什么第一个使用双打的exable工作,但不是我的?

3 个答案:

答案 0 :(得分:4)

这是依赖于操作系统的(正如@Basile Starynkevit在评论中更清楚地指出特定于实现的)。如你所知,malloc不会将其归零,但操作系统可以做到这一点(这明显取决于操作系统)。

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

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

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

答案 1 :(得分:1)

尝试为double中的第一个malloc分配相同的内存量:

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

小内存块的处理方式与glibc's malloc implementation中较大内存块的处理方式不同,您应该打印出返回指针的值,以便看到它是相同的内存块。

free可能会覆盖以前的内部簿记数据(可用内存块列表)。

答案 2 :(得分:0)

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

未定义行为的核心定义(是的,标准确实陈述了它们的含义&#34; undefined&#34;,具有讽刺意味的是)可以允许任何事情发生。这可能包括看似按预期工作,按照您的预期在一个案例中工作,而在另一个案例中工作等等。

您可能会看到不一致行为的原因(两个类似的示例,但只有一个按预期工作)通常归结为编译器如何在内存中组织数据,标准库实现如何在内存中组织数据,操作系统如何管理内存(因此malloc()返回最后free() d指针的可能性有多大,主机上有多少物理内存可用等等。这些都是互动的,并且不保证一个方式或其他。