Chinaunix

标题: 堆里面所有的内存是不是都是0? [打印本页]

作者: ethantsien    时间: 2011-11-14 14:31
标题: 堆里面所有的内存是不是都是0?
本帖最后由 ethantsien 于 2011-11-14 14:34 编辑
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main(int argc, char *argv[])
  4. {
  5.     char *foo;
  6.     foo = malloc(sizeof(char));
  7.     *foo = 'a';
  8.     printf("%s\n", foo);/* 此处不会出现段错误 */

  9.     int i;
  10.     for (i = 1; i < 100; i++) {
  11.         if (*(foo + i) == '\0') {
  12.             printf("%d\n", i);/* 发现后面的内存的位全是0 */
  13.         }
  14.     }

  15.     free(foo);
  16.     return 0;
  17. }
复制代码

作者: KBTiller    时间: 2011-11-14 15:00
*(foo + i)
已经越界了
没有意义
作者: ethantsien    时间: 2011-11-14 15:05
*(foo + i)
已经越界了
没有意义
KBTiller 发表于 2011-11-14 15:00


这只是测试后面的内存是不是都是0。

因为上面那句printf("%s\n", foo);能正常打印,没有段错误,我就想测试一下后面内存的位是不是都是0
作者: davelv    时间: 2011-11-14 15:09
系统一般都是按照页为单位保护内存的。
当然语言本身可以设置一定的保护机制,但是C语言没有设置。

至于这个0,虽说有的系统有意清除了原来的数据,但是不保证清除后一定是0,而且不能保证所有系统都会去做个清除操作。
要不然的calloc这个库函数就没有出现的必要了
作者: KBTiller    时间: 2011-11-14 15:11
回复 3# ethantsien


   从C语言的角度,不可能充分测试。从有限的测试,也无法得到任何结论   而且,我也想不出那能够有什么用处
作者: ethantsien    时间: 2011-11-14 15:33
系统一般都是按照页为单位保护内存的。
当然语言本身可以设置一定的保护机制,但是C语言没有设置。

至于 ...
davelv 发表于 2011-11-14 15:09



我的意思是,未使用过的内存,位都是0。cmalloc并非没有存在的必要,它可以把使用过的内存初始化为0,因为free后并不擦除原先的数据。
作者: davelv    时间: 2011-11-14 15:38
回复 6# ethantsien
你这个程序未使用,不代表别的程序以前没使用这块内存。
作者: davelv    时间: 2011-11-14 15:38
回复 5# KBTiller
也许有点用途,不过我也觉得用途不大。
作者: amarant    时间: 2011-11-14 22:16
从内核里分给用户的肯定是0页,但是用户空间反复分配和释放后就不一定了
作者: btdm123    时间: 2011-11-15 08:13
从内核里分给用户的肯定是0页,但是用户空间反复分配和释放后就不一定了
amarant 发表于 2011-11-14 22:16


没看过linux mm这一块,不过根据bach的书里描述的,内核并没有对回收的内存进行置0操作,是用硬件实现的?
作者: caiyijun1987    时间: 2011-11-15 08:41
未使用过的内存,位不都是0,要不calloc就没存在的必要
作者: siseniao    时间: 2011-11-15 08:48
整天搞这些没用的东西,这个和语言有一毛钱关系,有意义吗
作者: file3    时间: 2011-11-15 09:42
ethantsien 发表于 2011-11-14 14:31
  1.         if (*(foo + i) == '\0') {
  2.             printf("%d\n", i);/* 发现后面的内存的位全是0 */
  3.         }
复制代码
你判斷是0才輸出,當然他只能輸出0了!
作者: amarant    时间: 2011-11-15 14:36
回复 10# btdm123


    为了安全 内核不会给用户包含敏感信息的页的
作者: safedead    时间: 2011-11-15 14:56
我突然觉得某人推荐在free之前先bzero()一番的必要性了
作者: btdm123    时间: 2011-11-15 15:28
回复 14# amarant


    理解了,谢谢
作者: cfltdf    时间: 2011-11-15 15:34
改成1000之后的结果:
a
1
2
3
4
5
6
7
9
11
15
19
20
21
22
23
25
27
31
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
60
61
62
63
64
65
66
67
68
69
70
71
76
77
78
79
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
107
111
113
115
117
119
123
127
142
161
210
239
275
295
308
355
385
408
422
646
712
739
808
826
850
880
892
946
964
984
999

明显不全为0。
顺便这段代码被360误报。。。
作者: dingnning    时间: 2011-11-20 21:34
[quote]回复  ethantsien
你这个程序未使用,不代表别的程序以前没使用这块内存。
作者: digdeep126    时间: 2011-11-20 22:34
本帖最后由 digdeep126 于 2011-11-20 22:40 编辑

感觉这个例子还有继续研究的价值。为了方便研究,将原来的代码稍微修改一下:
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. int main()
  4. {
  5.         char    *foo;
  6.         int     i;

  7.         foo = malloc(sizeof(char));
  8.         *foo = 'a';
  9.         printf("foo: %s\n", foo);
  10.         printf("addr of foo: %p\n", foo);

  11.         for(i = 1; i < 100000; i++){
  12.                 if(*(foo + i) != 0){
  13.                         printf("%d\t", i);
  14.                         printf("%d\n", *(foo + i));
  15.                 }
  16.         }
  17.         printf("===============\n");
  18.         //for(i = -1; i > -9; i--)
  19.         for(i = -1; i > -10; i--)
  20.                 printf("%d\n", *(foo + i ));
  21.         free(foo);

  22.         return 0;
  23. }

复制代码
运行结果:
digdeep@ubuntu:~/uulp$ gcc -Wall -o memory memory.c
digdeep@ubuntu:~/uulp$ ./memory
foo: a
addr of foo: 0x938e008
12        -15
13        15
14        2
===============
0
0
0
17
0
0
0
0
Segmentation fault
digdeep@ubuntu:~/uulp$ ./memory
foo: a
addr of foo: 0x8284008
12        -15
13        15
14        2
===============
0
0
0
17
0
0
0
0
Segmentation fault
digdeep@ubuntu:~/uulp$

这里有几个疑问:
1)为什么每次运行时foo变量的地址不同,但是两个 for 循环输出的内容总是相同的?
2)第二个 for 循环当将 "i > -10;" 改为"i > -9;" 时,不会出现Segmentation fault,难道中间的8个字节是内存分配系统的“薄记信息”,而从第9个字节开始,就是访问另外一个程序申请的堆内存---所以报Segmentation fault?
期待大牛解释!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2