例如:
在堆段中手动malloc申请一段内存:
char* ptr = (char*)malloc(10);
........
free(ptr);
//ptr = NULL;假设这步忘记做了
那么这个ptr指针是不是依然指向那一块内存?
也就是说我接下来下次依然可以使用ptr指针?
貌似free的内存块是要够一页大小才会置换页面的
请问这个ptr如果没有赋值NULL会有什么后果?
另外,那么问题又来了
如果我双重释放ptr又会如何?
free(ptr);
free(ptr);
1
ryd994 2015-04-05 03:05:24 +08:00 1
依然指向
用的话可能segfault 重复free的话会segfault 赋值null就是为了避免重复free free NULL是安全的 |
2
ncisoft 2015-04-05 03:17:11 +08:00 via iPad
有这闲功夫发帖,都够写段代码测试下了,差评
|
3
RobberPhex 2015-04-05 11:17:17 +08:00 1
glibc是不允许多次free的,会出现异常:`Error in './a.out': double free or corruption`
另外,free小块内存后是可以访问的,因为那块内存还是被glibc管理的,不过这会破坏glibc的内存管理机制。 不过,释放大块内存的时候,glibc会将其归还给操作系统,此时访问会导致段错误。 //我猜测:mmap分配的内存,释放时会直接归还操作系统;brk/sbrk在顶端释放大量内存时会归还。 |
4
wind3110991 OP @ncisoft 谢谢
|
5
wind3110991 OP @RobberPhex 就是说free的对象要看是大还是小吧?谢谢你!你解答了我之前的一个问题,就是free之后的内存会不会马上归还给os
|
6
phoeagon 2015-04-05 12:35:48 +08:00 via Android
@wind3110991 还不还是implementation specific,不是标准定的,不要依赖编译器这种随时能改的实现
|
7
wind3110991 OP @phoeagon = =不太理解,就是说还是要以内核工作机制为准吗
|
8
msg7086 2015-04-05 16:36:16 +08:00 2
@wind3110991 就是说,一旦free了,这块内存就不属于你了。
接下来的访问就相当于偷着用,抓到就segfault,没抓到就是凑巧。 就像你租房期满,钥匙还给了房东。 接下来你再拿偷配的钥匙访问房子就可能会被抓。 |
9
gamexg 2015-04-05 22:11:12 +08:00
还有可能破化程序的其他部分。
你已经 free 了,其他代码 malloc 时有可能分配到相同位置,然后保存数据。 |
10
jedihy 2015-04-05 23:15:03 +08:00 via iPhone
因为后面用这个变量了吧,节省一条指令
|
11
wind3110991 OP @gamexg 谢啦~~我明白啦
|
12
khan 2015-04-30 10:43:43 +08:00
因为有很多地方都是这样判断
if (ptr == NULL) { ...do something } 你如果不置空, 后面打算怎么复用. free(ptr); ptr = NULL; //如果不打算复用指针, 这行代码意义不大. 也没有危险或潜在威胁 所以这种代码 称之为防御性代码. |
13
khan 2015-04-30 10:49:50 +08:00
@RobberPhex: 你说的内容有俩疑点
1. c++ 中我知道有new alloc 内存复用机制, 可以由 stdlib 来管理代码分配的内存. 但是 c 中的 alloc 就真的是直接调用系统的内存管理模块了. 应该不存在你说的 libc 管理内存的可能性. 2. mmap 是内存镜像文件. 我记得没错的话是处理超大型文件时不载入内存的一种实现方式. 直接用磁盘I/O来进行文件操作. 大文件载入内存导致爆内存的问题. 所以 mmap 本身应该可以认为是不占用内存的. 错漏之处还望斧正. |
14
RobberPhex 2015-04-30 12:36:05 +08:00 1
@khan malloc是libc提供的,在glibc的实现中,是有glibc自己的内存池的。另外,alloc应该也是libc提供的功能,但是linux没有这个内存调用;只有brk调用。
至于mmap,glibc在分配大块内存时也会用到,在逻辑上占用了内存,但是实际上在读写后,发生缺页中断后才会真正分配。 |
15
khan 2015-04-30 13:58:24 +08:00
@ryd994 这种情况其实称之为野指针. 情况不可预估. 可能你会发现某个堆的数据突然变化了. 从而导致各种灵异现象.
另外如果 = NULL, 是空指针, 和内核地址重叠. 如果强制访问. 持有进程会被内核杀死. |
18
ryd994 2015-04-30 15:04:38 +08:00 2
|
19
khan 2015-04-30 15:09:44 +08:00
@ryd994 在@RobberPhex的提示下, 正在看Ptmalloc2的 Free 部分实现. 证实了你的说法.
|
20
qiuyi116 2015-05-27 22:55:42 +08:00
free但是不给赋NULL就是自己挖坑,,亲测啊。。因为free知识把ptr指向的内存资源释放归还给了OS,但是呢,ptr还是指向这个虚拟地址的啊。访问ptr的值就会Segmentfault.....
|
21
wind3110991 OP 嗯嗯,我也测试过,如果没有赋值ptr = NULL
之后还是会保留ptr指向的虚拟地址 |