免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: _Erics
打印 上一主题 下一主题

求助:为何还能访问delete之后的空间 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2006-05-22 09:36 |只看该作者
这个问题的本质是
可不可以访问的控制是以页(4096字节)为单位的。而new, delete, malloc, free是以字节为单位的。

如重复许多次(比如32次)malloc 1个字节的指针分别给p0,p1, ...p31,然后又释放了第一次malloc的那个字节p1。p1一定是可以访问的。这种情况和glibc内存管理策略无关。

论坛徽章:
0
12 [报告]
发表于 2006-05-22 11:05 |只看该作者
原帖由 _Erics 于 2006-5-21 18:53 发表


赞同JohnBull的第一个观点,但是对第二个观点不是很理解:
我写了一个类似的C程序,把new和delete改成了malloc和free,
但是free之后的内存空间还是可以被访问的。
看来要补一下libc对进程堆内存的管理了


呵呵,你确实没有理解第二句话.
他的意思是用C++的人对本质理解不深,只会new 和delete.
:wink::wink::wink:
当然也可能不是这个意思,我的理解而已

论坛徽章:
0
13 [报告]
发表于 2006-05-23 08:47 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
14 [报告]
发表于 2006-05-23 13:02 |只看该作者
原帖由 _Erics 于 2006-5-19 10:31 发表
先看两段代码,引出对下面问题的思考:
  代码段1:  
  #include <iostream>
  using namespace std;
  int main()
{
   int * p = new int;
   delete p;
   *p = 3;
   cout<<*p<<en ...


一般是这样使用:delete p;
                        p=NULL;   
如果没有P=NULL,那么p中还是存放的原来那块内存的地址,所以你可以继续使用它!

论坛徽章:
0
15 [报告]
发表于 2006-05-23 23:20 |只看该作者
原帖由 _Erics 于 2006-5-21 18:53 发表
赞同JohnBull的第一个观点,但是对第二个观点不是很理解:


C++隐藏了太多的机制和调用,它的“算符”太复杂,这里的“复杂”就是一个算符(就比如delete)不仅仅是一个“计算”,而是一系列操作,要命的是这些“算符”甚至还需要依赖于某些库。相对而言,C语言更靠近汇编语言。据我所知,现阶段的CPU都是从汇编的角度出发设计的,还没有从某种高级语言的角度出发进行设计的。

所以对于操作系统这样靠近硬件的实现目标来说,用C描述最直接,最省力。如果用C++,你除了描述内核的算法之外,还得重新手工实现所有的C++语言元素(比如上面说的对象操作以及异常流等),如果compile-time实现还算简单,但是那与用C何异?
而C就简单多了,它至多是一个超级宏汇编(如上:现阶段的CPU都是从汇编的角度出发设计的),你不必仅仅为了满足这个语言的某些要求而不得不做很多额外的工作,他需要的CPU都有了。

论坛徽章:
0
16 [报告]
发表于 2006-05-24 01:48 |只看该作者
楼上说的不妥呀!!

没什么天生的因素,C++就一定比C要慢。

大多数情况下,只有C++的 class 含 virtual 机制时才会比C要慢!

大多数情况下,C++并不会比C要慢

例如: C++ delete 操作符实现上。一般为:

void operator delete(void *ptr) {
      if (ptr)
          free(ptr);
}

只是,当分配数组时情况就复杂多了。

论坛徽章:
0
17 [报告]
发表于 2006-05-24 10:46 |只看该作者
没记错的话,free的时候应该是brk系统调用来调整堆的大小,而内核这时也并不会真正释放这块内存,也许是为了缓存,也许是因为该页中还有其他内存被使用中,所以进程页表中并没什么变化,这样你就依然可以访问这块物理内存。加100没问题,加200有问题,我猜想可能加200的时候超出一个页了。

论坛徽章:
0
18 [报告]
发表于 2006-05-25 10:17 |只看该作者
原帖由 mik 于 2006-5-24 01:48 发表
楼上说的不妥呀!!

没什么天生的因素,C++就一定比C要慢。

大多数情况下,只有C++的 class 含 virtual 机制时才会比C要慢!

大多数情况下,C++并不会比C要慢

例如: C++ delete 操作符实现上。一般为 ...


我说过快、慢的问题吗?怎么语文水平这么差!

那么请问free()在什么地方实现的?编写内核的时候怎么能使用标准库?你势必亲自实现!
原帖由 _Erics 于 2006-5-21 18:53 发表

看来要补一下libc对进程堆内存的管理了

对你也有相同的问题。内核怎么使用libc?

[ 本帖最后由 JohnBull 于 2006-5-25 10:20 编辑 ]

论坛徽章:
0
19 [报告]
发表于 2006-05-25 10:39 |只看该作者
逻辑反了。

free的时候是LIBC 判断要不要调sys_brk. 一旦调用sys_brk来释放内存了, 内核一定要做真正的释放,进程表中一定有变化。

原帖由 coco520 于 2006-5-24 10:46 发表
没记错的话,free的时候应该是brk系统调用来调整堆的大小,而内核这时也并不会真正释放这块内存,也许是为了缓存,也许是因为该页中还有其他内存被使用中,所以进程页表中并没什么变化,这样你就依然可以访问这块 ...

论坛徽章:
0
20 [报告]
发表于 2006-05-25 10:42 |只看该作者
原帖由 思一克 于 2006-5-25 10:39 发表
逻辑反了。

free的时候是LIBC 判断要不要调sys_brk. 一旦调用sys_brk来释放内存了, 内核一定要做真正的释放,进程表中一定有变化。



恩,实际上free()并没有调用brk或者sbrk,而只是合并了内部的空闲块表而已。
可能是怕发生抖动。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP