由malloc()`分配的内存有哪些内容?

时间:2016-05-12 10:50:16

标签: c initialization malloc dynamic-memory-allocation

在使用malloc()分配内存空间后,我很清楚指针究竟是什么?该联机帮助页告诉我calloc()将分配的内存空间初始化为零。

  

malloc()函数分配大小字节并返回指向已分配内存的指针。 内存未初始化。如果size为0,则malloc()返回NULL或一个以后可以成功传递给free()的唯一指针值。

  

calloc()函数为每个大小为字节的nmemb元素数组分配内存          并返回指向已分配内存的指针。 内存设置为零。如果nmemb或          size为0,然后calloc()返回NULL或稍后可以返回的唯一指针值          成功传递给free()。​​

我在C中为C(哈哈)创建了一个非常简短的示例程序:

int main() {
    char *dynamic_chars;
    unsigned amount;
    printf("how much bytes you want to allocate?\n");
    scanf("%d", &amount);

    dynamic_chars = (char*)malloc(amount*sizeof(char));
    printf("allocated:\n%s\n", dynamic_chars);

    free(dynamic_chars);
    return 0;

}

然而,在执行此代码时,它只输出任何内容。如果我初始化内存我自己,例如使用循环使用0xFFFF初始化每个字节,那么程序会向我显示我期望的内容。内存空间实际存在,因为我不会收到错误声称我正在尝试访问未初始化的变量。

由于内存空间通常没有被删除但被标记为可重写,我想知道通过执行我的程序,我是否应该能够看到以前使用过的随机内存字节?但我什么都看不到,所以我对malloc()的确切运作方式感到很困惑。

EDIT1

关于malloc()或者通常使用内存的另一件事,我的程序很有趣: 如果我使用calloc()来分配内存,我可以跟踪我的程序的实际内存使用情况,例如监控它。例如,如果我告诉我的程序,每calloc()分配1.000.000.000字节的内存,我将在我的系统监视器中看到以下内容: Memory consumption when using <code>calloc()</code>

你可以想象,当使用malloc()时,我什么也看不见。我明白,只是通过分配内存,我当时并没有真正使用它,但我仍然感到困惑的是为什么我的操作系统(unix衍生物)不会将其识别为使用它。由于malloc()就像calloc()一样将物理地址返回到我没有得到的内存位置,这个内存区域似乎实际上并没有被操作系统保留。那么我可以在系统监视器中看到它吗? 如果我想将此作为一个新问题发布,请告诉我。但我认为,因为问题仍然是关于malloc()如何运作,它适合这里。

3 个答案:

答案 0 :(得分:13)

不,malloc()返回未初始化的内存,其内容不确定。因此,尝试使用该值调用undefined behavior

引用C11,附件§J.2,未定义的行为

  

使用malloc函数分配的对象的值

在这种情况下,%s需要一个以null结尾的char数组。但是,dynamic_chars的内容是不确定的,因此很可能根本没有空终止符,这将导致超出范围的内存访问,从而调用UB。

引用C11,章节§7.22.3.5,malloc函数(强调我的):

  

malloc函数为大小由size指定的对象分配空间   ,其值不确定。

那就是please see this discussion on why not to cast the return value of malloc() and family in C.

答案 1 :(得分:3)

C语言未定义内存块包含的内容。在实践中,它很可能只是简单地包含先前物理存储器中的内容。

如果您的程序以前使用过该内存并且释放了内存,那么您很可能只会获得其中的内存。如果是操作系统新请求的内存,您将获得操作系统放入的内存。大多数操作系统返回专门设置为“零”字节的内存,因为如果内存中仍然包含之前其他程序中的内容,则会出现安全问题。

这些都不受任何标准的保证,这正是大多数系统在实践中所做的。

答案 2 :(得分:2)

malloc为您分配内存并设置指向它的指针。它不以任何方式初始化内存,因此分配的内存区域可以包含任何内容。由于它不包含字符串,因此您无法通过打印字符串来读取其内容。相反,你可以逐字节打印,如下所示:

for(int i=0;i<amount*sizeof(char);i++)
{
    printf("%02x", (unsigned)dynamic_chars[i]);
}