1

我只是尝试为 c 字符串分配 10 个字节并在没有分配任何内容的情况下打印。我打印了 cstring 的大小。但是结果和我想象的完全不同。由于 malloc 只分配原始内存,我认为它会打印任何垃圾值。而且由于我试图打印 c 字符串的大小,我认为行为应该是未定义的。但他们都打印空字符我认为这是我的代码。

int main(void)
{
    int i;
    char * c = (char *)malloc(10);
    for(i=0; i<20; ++i)
    {
        printf("%c.\n", *(c+i));
    }
    return 0;
}

我看到了 20 行“。”。谁能解释一下?我在linux下跑过这个,用的gcc最新版 谢谢

4

3 回答 3

2

每当 Linux 内核将“新”内存页面映射到用户空间到您的进程时,它会用零填充该页面,因此您无法找到另一个进程可能留在这些内存地址中的任何数据残留,因为该内存可能属于另一个进程(以及另一个用户),其中包含秘密数据,例如密码、密钥等(如果您感兴趣,内核会调用linux/gfp.hunsigned long get_zeroed_page(gfp_t gfp_mask);中定义的函数)

只要此页面与您的进程相关联,就不会再次用零填充该页面,因此即使您释放了内存,以下代码仍应打印出您之前放入的值:

#include <stdlib.h>
#include <stdio.h>


int main(){
    char* test1 = malloc(100);
    int i;
    for(i=0; i<5; i++){
        test1[i] = i+'A';
    }
    free(test1);
    char* test2 = malloc(100);
    for(i=0; i<5; i++){
        printf("%c.\n",test2[i]);
    }
    return 0;
}

这应该会给你以下输出(虽然不能保证):

$ ./a.out 
A.
B.
C.
D.
E.
于 2012-06-03T04:00:35.660 回答
1

它还没有被初始化。需要先将其设置为一个值,然后您才能看到任何有用的信息。它只是打印了该内存地址中已经存在的内容(除非设置了一些编译器选项),这很可能只是 0。

于 2012-06-03T02:39:45.757 回答
0

如果您正在读取数组,则行为仍应未定义。你的结果只是意味着内存在分配之前已经存储了 '\0' 。使用 calloc() 将数组初始化为零。

于 2012-06-03T02:47:32.507 回答