BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #94258同步于 2016/12/15
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

free到底做了什么?

byr10086
2016/12/15镜像同步11 回复
``` char * p = (char*) malloc(27); for(int i = 0;i<26;++i){ *(p+i) = 'a'+i; } *(p+26) = '\0'; for(int i = 0;*(p+i) != '\0';++i){ cout<<*p; } free (p); for(int i = 0;*(p+i) != '\0';++i){ cout<<*p; } 为什么最后一个for循环不能正常输出26个字母? 求指导
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
nuanyangyang机器人#1 · 2016/12/15
free以后,把分配的内存释放了。内存释放之后再访问,是”未定义行为“。不能正常输出是正常的。
byr10086机器人#2 · 2016/12/15
【 在 nuanyangyang 的大作中提到: 】 : free以后,把分配的内存释放了。内存释放之后再访问,是”未定义行为“。不能正常输出是正常的。 话虽这么说,但是在刚把内存free掉以后,里面的内容应该没有改变才是啊? 但为什么多次运行程序后,输出都不是我所预期的。。。
NachtZ机器人#3 · 2016/12/15
free掉的内存,里面是什么,就不是一件可以预估的事情。它可以是原来的东西,也可以是一堆乱码,还可能是一堆0。取决于编译器。不要用任何逻辑去判断未定义行为,因为这种地方,编译器想怎么做就怎么做。 【 在 byr10086 (nieng) 的大作中提到: 】 : 话虽这么说,但是在刚把内存free掉以后,里面的内容应该没有改变才是啊? 但为什么多次运行程序后,输出都不是我所预期的。。。
nuanyangyang机器人#4 · 2016/12/15
【 在 byr10086 的大作中提到: 】 : : 话虽这么说,但是在刚把内存free掉以后,里面的内容应该没有改变才是啊? 但为什么多次运行程序后,输出都不是我所预期的。。。 不能这么想。C语言把free之后读取定为“未定义行为”,就是为了让内存分配器自由行事。你不能认为“刚free”所以“里面内容没有变”。刚好相反,某些内存分配器会在free之后把里面的内容全部用某种poison value覆盖,这样程序会读到某些很搞笑的值,程序猿一看就知道发生free后访问的错误了。有时候,标准库用memory map来实现内存分配,free之后可能就把一个page的内存unmap了,这会导致CPU的mmu删除这块地址区域到物理内存的映射,然后再访问程序就崩溃了。 总之free之后访问是“未定义行为”,从什么都不发生到机器冒烟都有可能发生。
default机器人#5 · 2016/12/16
想知道到底做了什么这些事情,可以学汇编语言和逆向工程 发自「贵邮」
byr10086机器人#6 · 2016/12/16
【 在 NachtZ 的大作中提到: 】 : free掉的内存,里面是什么,就不是一件可以预估的事情。它可以是原来的东西,也可以是一堆乱码,还可能是一堆0。取决于编译器。不要用任何逻辑去判断未定义行为,因为这种地方,编译器想怎么做就怎么做。 记住了,谢谢你!
byr10086机器人#7 · 2016/12/16
【 在 nuanyangyang 的大作中提到: 】 : : 不能这么想。C语言把free之后读取定为“未定义行为”,就是为了让内存分配器自由行事。你不能认为“刚free”所以“里面内容没有变”。刚好相反,某些内存分配器会在free之后把里面的内容全部用某种poison value覆盖,这样程序会读到某些很搞笑的值,程序猿一看就知道发生free后访问的错误了。有时候,标准库用memory map来实现内存分配,free之后可能就把一个page的内存unmap了,这会导致CPU的mmu删除这块地址区域到物理内存的映射,然后再访问程序就崩溃了。 : 总之free之后访问是“未定义行为”,从什么都不发生到机器冒烟都有可能发生。 明白了,谢暖神
byr10086机器人#8 · 2016/12/16
【 在 default 的大作中提到: 】 : 想知道到底做了什么这些事情,可以学汇编语言和逆向工程 : 发自「贵邮」 改天一定学
smilehehe机器人#9 · 2016/12/16
只有这样才会有UAF漏洞嘛,我们才有饭吃[ema1][ema1] 【 在 NachtZ 的大作中提到: 】 : free掉的内存,里面是什么,就不是一件可以预估的事情。它可以是原来的东西,也可以是一堆乱码,还可能是一堆0。取决于编译器。不要用任何逻辑去判断未定义行为,因为这种地方,编译器想怎么做就怎么做。