一道关于free的面试题

5 篇文章 0 订阅

2). void Test(void){

char *str = (char *) malloc(100);

strcpy(str, “hello”);

free(str);

if(str != NULL){

strcpy(str, “world”);

printf(str);

}

}

请问运行Test 函数会有什么样的结果?

答:输出“world”

 

C并不明确禁止use-after-free的情形(尽管这是一类很隐蔽而严重的错误)。这是因为C的malloc(3)系列函数实际上是操作系统内存管理接口的一个封装,在free时,通常并不同时释放进程占用的内存页,相反,它仅仅将这部分内存在malloc(3)内部结构中标记为可再分配。

后续的内存访问,由于内存页仍然是可读写的权限,因此不致导致访问异常。然而,由于malloc(3)已经不知道这部分内存仍在使用,因此,后续的malloc(3)操作有可能将这部分内存再次分配给程序的其它部分使用。由于仍然保有指向此内存块的指针,程序将陷入十分危险的状态,有可能崩溃,也有可能表面上看什么事也没有。

作为良好编程习惯的一部分,通常希望将free()之后的指针置为NULL,以便让程序在存在悬挂指针的时候尽早崩溃以便排除错误。然而,这一操作也会降低一些性能,另一方面,由于C并未提供指针的逆向追踪机制,因此这种做法并不一定能起到作用。新一些的、特别是面向对象的编程语言中,通常提供了引用计数、分代回收等垃圾回收机制来阻止此类情形发生。垃圾回收在几年前曾经是十分热门的研究课题,如果对这方面有兴趣,可以参考人民邮电出版社出版的《垃圾收集》等相关书籍。

对于C程序员来说,过硬的处理内存操作是最重要的基本能力之一。

 

long add ----------------------------------------------

类似的,malloc分配时也是对内存进行标记。不会对内容作任何改变。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值