初学者疑问:操作系统怎么管理栈内存的呢?(解决后马上给分)

vivanboy 2006-03-20 02:19:46
大家都知道创建动态内存,如果失败会返回NULL;但是如果栈内存使用完毕后,在栈内创建一个对象,会出现什么问题呢?

比如:
const int sizeOfInt = 250 << 20;
int testInt[sizeOfInt] = {0};
Sleep(100000);

为什么程序挂在这里时,任务管理器显示此进程仅仅占数百K内存,而不是250M呢?
...全文
224 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
pgmsoul 2006-03-21
  • 打赏
  • 举报
回复
不同的编译器和设置是不一样的,我的VC7.0只要分配1M的数组就说溢出.
vivanboy 2006-03-21
  • 打赏
  • 举报
回复
菜菜鸟:
不会吧,我的sizeOfInt比你大多了都可以编译通过(可能和内存大小有关吧,我的是256M内存),运行起来也没有问题。就是看不到系统资源的大幅度减少,真是奇怪:(
iamcaicainiao 2006-03-21
  • 打赏
  • 举报
回复

int main(int argc, char* argv[])
{

const int sizeOfInt = 500000;
int testInt[sizeOfInt] = {0};

}
这样都已经不行了。编译是通过。执行起来就出错了。估计就是分配不了这么多栈内存。
iamcaicainiao 2006-03-21
  • 打赏
  • 举报
回复
早起的鸟儿有虫吃。好名字。
这个问题我也困惑。关注。是不是已经溢出啦?好像我编译不通过嘛。
睡在床板下_ 2006-03-21
  • 打赏
  • 举报
回复
是自己 以前哪本书 上抄下来的笔记, 应该有点帮助~~
睡在床板下_ 2006-03-21
  • 打赏
  • 举报
回复
栈(stack)为线程所有,是线程的一种特殊的内存结构。
系统为每一个线程分配一个stack, windows默认的stack大小为1M ,但是连接时指定 “/stack" 的开关可以调整stack的大小,格式: /stack: reserve[,commit]

stack具有“先进后出”的特点,局部变量的分配,函数传递的参数,push指令等都是在线程中的stack 中操作的。
线程执行时,esp总是指向栈顶(高地址端),随着入栈的深入,esp 越来越小,向栈底推进(低地址端)。系统如何防止stack溢出的呢??

假设 。0030000H~00130000H 为stack区域,那么该区域有三个块:
1: 00030000H~00092000H 为保留态(块1),大小 401408B
2: 00092000H~00093000H 为带有RAGE_GRARD 保护属性的 4kb 私有块(块2)
3: 00093000H~00130000H 为使用态(块3)

当线程执行时,首先使用stack中的块3,当块3 用完后,将访问块2。由于块2 有RAGE_GUARD保护属性,这时发生异常,系统接过控制权,它将重新分配块2和块1,提交部分的内存供进程使用。
这种异常将发生多次,以保证进程需要的栈空间,一直到靠近栈底部的倒数第二个页面被提交,但是不管怎么样,栈底部的最后一个页面,总是处于保留态,进程访问保留态的 页面时,将会违规,系统将“杀死”进程。保留块其实就象一堵墙,堵着你,不让你溢出。。
通俗的讲:stack就象吃甘蔗,“吃一截才去一截”。。。

这是 windows 2000/xp stack的特点,好处是物理存储器 提交总是 “物尽其用”,避免浪费。

heap : heap为进程所有,heap的默认大小也为1M,也可以再连接时调整大小。在一个进程中可以分配多个heap
heap 分为可生长heap和 不可生长heap。 当建议不可生长heap时,最大可分配的大小为7FFF8H。
睡在床板下_ 2006-03-21
  • 打赏
  • 举报
回复
windows系统 默认 堆 和 栈的大小 是 1M,但是 也可以自己调整

具体的话,我要查查资料 , 一时想不起来了。。。
待会我去图书馆 把它 抄上来~~
vivanboy 2006-03-21
  • 打赏
  • 举报
回复
还没有出现内存溢出现象阿,运行很正常的啊

还没有看到一个很令人信服的答案:(
dadacool 2006-03-21
  • 打赏
  • 举报
回复
因为程序占用了不是系统分配给这个程序的内存,非法操作,而C++相对的对查错放宽,所以这样会造成内存溢出,我用VC的编译器是可以查出错误的
vivanboy 2006-03-20
  • 打赏
  • 举报
回复
ugg(逸学堂(exuetang.net))
我的数组元素是250<<20个啊,总共是250*4M内存啊,VC编译通过啊

ps:
更正一下我上面所说的一个错误:应该是1G内存,而不是250M
逸学堂 2006-03-20
  • 打赏
  • 举报
回复

1.
>大家都知道创建动态内存,如果失败会返回NULL;
// 指针为空,并且抛出bad_alloc异常。

2.
>为什么程序挂在这里时,任务管理器显示此进程仅仅占数百K内存,而不是250M呢?
用的windows?任务管理器指示的是“物理内存”而不是“逻辑内存”。
~~~~~
栈上的空间申请,最大是2M(VC编译器)。
vivanboy 2006-03-20
  • 打赏
  • 举报
回复
1.
>大家都知道创建动态内存,如果失败会返回NULL;
不知道你在哪里听到的这句。它并不一定时真的,比如malloc分配一个大于32位的内存时,就不是这样。

那是怎样阿?

2.
>为什么程序挂在这里时,任务管理器显示此进程仅仅占数百K内存,而不是250M呢?
用的windows?任务管理器指示的是“物理内存”而不是“逻辑内存”。
物理内存显示采用了几百K,而虚拟内存走势图也看不出上升了250M啊?为什么啊?
dongpy 2006-03-20
  • 打赏
  • 举报
回复
但是如果栈内存使用完毕后,在栈内创建一个对象,会出现什么问题呢?
================================
这里的栈内存是指虚拟内存,而不是指物理内存。
firetoucher 2006-03-20
  • 打赏
  • 举报
回复
>大家都知道创建动态内存,如果失败会返回NULL;
不知道你在哪里听到的这句。它并不一定时真的,比如malloc分配一个大于32位的内存时,就不是这样。

>但是如果栈内存使用完毕后,在栈内创建一个对象,会出现什么问题呢?
每个操作系统的处理不一样。从简单的忽略掉这句语句到中止程序都可能。

>为什么程序挂在这里时,任务管理器显示此进程仅仅占数百K内存,而不是250M呢?
用的windows?任务管理器指示的是“物理内存”而不是“逻辑内存”。


FT
--
Anything one man can imagine, other men can make real.
defyer007 2006-03-20
  • 打赏
  • 举报
回复
楼主的签名有意思:)
早起的鸟儿有虫吃,早起的虫呢?答:被鸟吃
呵呵
defyer007 2006-03-20
  • 打赏
  • 举报
回复
这个不同的OS处理不一样的,有些报内存不够,有些可能直接丢掉这个内存申请,或者有可能杀死某个不重要的进程或释放不必要的资源腾出内存空间...
dongpy 2006-03-20
  • 打赏
  • 举报
回复
但是如果栈内存使用完毕后,在栈内创建一个对象,会出现什么问题呢?
===================================================================
操作系统给用户进程的堆栈设定一个上限值,如果堆栈大小超过这个值,就会报错“stack overflow”,就是堆栈溢出了。

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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