书上常用“堆栈”一词,难道堆和栈是一回事吗?

Xsean 2001-07-22 08:37:24
...全文
364 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
jerry2 2001-08-08
  • 打赏
  • 举报
回复
受不了.....
fatty 2001-08-08
  • 打赏
  • 举报
回复
不要吵了!
pitchstar 2001-07-24
  • 打赏
  • 举报
回复
在 i386 上,堆的存取比栈要快,堆是指数据区,以 DS 寄存器为段基址寻址,“由 CSS、SS、ES、FS、GS 寻址的段中数据的指令比那些由 DS 寻址的指令要长一个字节,这使得引用非 DS 的段在程序存储量和执行时间开销上稍大一些,但也大不了多少”(《保护方式下的 80386 及其编程》 24 页)。

在分配内存时的开销和运行时存取的速度是两个概念,我觉得楼上有人混淆了这个问题,但是就运行中分配内存来说,可能实际问题也不象楼上描述的那样,分配/释放内存编译器总是在堆中操作,所以楼上所说的问题存在于堆中,假设一种情况:编译器不使用堆,而使用栈,那内存泄露碎片的情况会好吗?我觉得不会,因为这个问题是分配内存时的算法,及用户程序实现的问题,而和堆还是栈没有关系。
pitchstar 2001-07-24
  • 打赏
  • 举报
回复
alwaysakid(老A),你在说我吗?
本来不想说伤人的话,但是你的脸皮也太厚了一点,无知不要紧,自以为是就不上路了。

我自知水平不够,所谓“大战”是因为由于我还存在一些疑问,但知识所限,没办法跟你探讨。开个玩笑,你认真了!
fatty 2001-07-24
  • 打赏
  • 举报
回复
所问非所答!
书上常用“堆栈”一词,难道堆和栈是一回事吗?
---书上说"堆栈"的时候是指"栈",说"堆"的时候才是指"堆"!
alwaysakid 2001-07-24
  • 打赏
  • 举报
回复
我根本无意和你作战,我是看到你写的东西怕误人子弟才发言的。
alwaysakid 2001-07-24
  • 打赏
  • 举报
回复
但是dos下面
ds:0001 != cs:0001 != ss:0001 != es:0001
你还觉得一样吗,你真的很应该好好学习学习,本来不想说伤人的话,但是你的脸皮也太厚了一点,无知不要紧,自以为是就不上路了。
微星1234 2001-07-24
  • 打赏
  • 举报
回复
Windows下的所有段都相同,起决于一个选择子,
用户程序:Win95下0x0137, win98下0x167
系统:0x0028
:)
pitchstar 2001-07-24
  • 打赏
  • 举报
回复
哦,露怯了,呵呵 等我学习学习再跟你大战 300 合
alwaysakid 2001-07-24
  • 打赏
  • 举报
回复
你也可以说他是用ds来寻址的,因为win32下面:
cs:00400000 == ds:00400000 == ss:00400000 == es:00400000 .....
线性地址空间。
pitchstar 2001-07-24
  • 打赏
  • 举报
回复
我想可以这么归结问题:
我原来以为堆是指用 ds 来寻址的,栈是通过 ss 来寻址的。
可是你说 “win32 的堆并不在数据段上面分配”,他是怎样寻址呢?
或者给我推荐本书看~先谢了
whfsr 2001-07-24
  • 打赏
  • 举报
回复
看来你还没看过数据结构,等你看过后你就会明白,
alwaysakid 2001-07-24
  • 打赏
  • 举报
回复
>>假设一种情况:编译器不使用堆,而使用栈
编译器从来不选择堆还是栈,这些事程序员决定的
void func()
{
static int a; <-- 数据段分配
int a <-- 栈分配
int * p = new...<-- 堆分配
}

在win32下面,所有的new,calloc,malloc,realloc,free,最终都要调用heapalloc,heapfree,heaprealloc,因为堆最终是由系统管理的,系统可能需要进一步调用
VirtualAlloc....

dos下的堆是c的运行库管理的,事实上分配是在数据段上分配(win32的堆并不在数据段上面分配,只有静态变量,常量和全局变量在数据段上面,而且win32的段和dos的段也不是一个概念)

越扯越远了...反正dos的堆和win32的堆不是一回事。
pitchstar 2001-07-24
  • 打赏
  • 举报
回复
alwaysakid(老A)
我所知就这些,请你说详细点,现在的堆不同在哪?
qian 2001-07-24
  • 打赏
  • 举报
回复
楼上说的都有理,仔细看一下就明白了。
alwaysakid 2001-07-24
  • 打赏
  • 举报
回复
楼上所说是dos下面的概念(以 DS 寄存器为段基址寻址...),在32位操作系统下面是完全错误的。dos下面的堆的确是通过ds访问,因为dos的堆和现在的堆完全两回事。
jerry2 2001-07-23
  • 打赏
  • 举报
回复
堆执行实时分配,所以是动态分配。
至于大量使用就会减慢速度。
james_razor 2001-07-23
  • 打赏
  • 举报
回复
专贴自:
http://www.microsoft.com/china/msdn/library/techart/heap3.asp
james_razor 2001-07-23
  • 打赏
  • 举报
回复
什么是常见的堆性能问题?
以下是您使用堆时会遇到的最常见问题:

分配操作造成的速度减慢。光分配就耗费很长时间。最可能导致运行速度减慢原因是空闲列表没有块,所以运行时分配程序代码会耗费周期寻找较大的空闲块,或从后端分配程序分配新块。


释放操作造成的速度减慢。释放操作耗费较多周期,主要是启用了收集操作。收集期间,每个释放操作“查找”它的相邻块,取出它们并构造成较大块,然后再把此较大块插入空闲列表。在查找期间,内存可能会随机碰到,从而导致高速缓存不能命中,性能降低。


堆竞争造成的速度减慢。当两个或多个线程同时访问数据,而且一个线程继续进行之前必须等待另一个线程完成时就发生竞争。竞争总是导致麻烦;这也是目前多处理器系统遇到的最大问题。当大量使用内存块的应用程序或 DLL 以多线程方式运行(或运行于多处理器系统上)时将导致速度减慢。单一锁定的使用—常用的解决方案—意味着使用堆的所有操作是序列化的。当等待锁定时序列化会引起线程切换上下文。可以想象交叉路口闪烁的红灯处走走停停导致的速度减慢。
竞争通常会导致线程和进程的上下文切换。上下文切换的开销是很大的,但开销更大的是数据从处理器高速缓存中丢失,以及后来线程复活时的数据重建。

堆破坏造成的速度减慢。造成堆破坏的原因是应用程序对堆块的不正确使用。通常情形包括释放已释放的堆块或使用已释放的堆块,以及块的越界重写等明显问题。(破坏不在本文讨论范围之内。有关内存重写和泄漏等其他细节,请参见 Microsoft Visual C++(R) 调试文档 。)


频繁的分配和重分配造成的速度减慢。这是使用脚本语言时非常普遍的现象。如字符串被反复分配,随重分配增长和释放。不要这样做,如果可能,尽量分配大字符串和使用缓冲区。另一种方法就是尽量少用连接操作。
james_razor 2001-07-23
  • 打赏
  • 举报
回复
堆存取比栈快?
在堆中分配内存要查找合适大小的块,释放内存需要合并碎块,堆的速度会比栈快?我想不通。
加载更多回复(14)

16,551

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧