线程里New操作分配的存储空间,用的是线程的堆栈吗? 函数里New操作分配的存储空间,用的是函数的运行栈吗?那函数结束时,应该自动释放呀!何必Delete? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 不是这样,如果你没有用new申请内存空间的话,系统会为你定义的变量自动分配一段内存地址,但你用了new以后就不行了,不然就会造成内存泄漏(老师教的)就是这个变量空占着内存但没有指向它的指针了谁都访问不到,因为我还没学操作系统,内部的机制我不大清楚,但我肯定这是必须的。 今天才知道还有线程的堆栈,有点混乱。我只知道用new申请的资源一定要释放的。 new应该用的是堆(heap)而不是堆栈(stack)吧。 有关内存管理问题,很多书上都有比较详尽的介绍,基本上也就如wzwind(风的脚印)所述。内存分配主要分为堆栈(stack)内存分配和堆(heap)内存分配。当你定义了一个局部变量时,系统会自动在堆栈中为该变量分配空间,当程序运行到堆栈变量的作用范围之外时,空间会自动释放。而堆则是在程序代码段和堆栈之外的内存段,这部分的内存是可以动态分配的,需要程序员来管理(分配和释放)。对于同一个进程的多个线程而言,它们之间是共享同一内存空间的,虽然每个线程都有自己的堆栈,但它们使用同一块堆。你可以把线程理解为一个函数或过程,它可以有自己的局部变量,而用new分配的变量相当于全局变量,可供同一进程的其它线程共享,所以线程退出后,应及时释放,否则这段空间就一直被你占用着。 new 是分配内存的他可不管你在哪里分配.用他分配内存之后,用完记得释放delete,oK?内存泄漏可不是闹着玩的 拜托,满意的话给几分吧,我才来没多久,需要充电 你可以跟蹤一下new就知道,實際上new是通過調用HeapCreate來分配空間的,也就是用的是進程的默認堆,自然要用delete來調用HeapDestory()來釋放啦 heap 与stack 的区别,基础知识,看书去吧。 heap 与stack 的区别?看那些书? 主 题:堆和栈有什么区别?作 者:Neo2D所属论坛:Delphi问题点数:20回复次数:10发表时间:2001-5-10 22:31:00 本来该在VC论坛问,但这里人多呀:) 回复贴子: 回复人:colacoca(可口可乐) (2001-5-11 1:25:00) 得3分 堆是先进先出原则栈是后进先出原则 回复人:BigBen(江南草) (2001-5-11 8:17:00) 得3分 在win32和win16中,堆(heap)是指可供分配的内存,进程中可动态分配。这不同于数据结构中所讲的堆。 回复人:sanjianxia(三剑侠) (2001-5-11 9:05:00) 得0分 两种都可动态分配。 回复人:BCB(:)) (2001-5-11 9:14:00) 得3分 局部变量在栈中分配,动态申请的变量空间在堆中分配; 回复人:skimwater(掠水惊鸿) (2001-5-11 9:22:00) 得0分 有道理。 回复人:wanwangzhiwang(万王之王) (2001-5-11 9:32:00) 得0分 呵,我对这两个东东不是很了解,当个听众!大家继续! 回复人:cq_xiaolong(fg) (2001-5-11 9:49:00) 得0分 那怎么应用堆跟栈呢?关注! 回复人:maozefa(之源) (2001-5-11 10:20:00) 得5分 在传统的C中堆和栈实际是一块物理内存,堆主要用来动态分配内存,从堆栈内存的低端向上分配;而栈主要用来传递函数参数、返回值和局部参数内存分配,是从堆栈内存的高端向下分配,俗称压栈和出栈。 回复人:Kingron(WinAPI) (2001-5-11 10:32:00) 得1分 看看TStack(堆栈)跟TQueue(队列)类吧。帮助上面有的。 回复人:BCB(:)) (2001-5-11 10:50:00) 得5分 一般的子程序的入参及局部变量都放在栈中的,子程序结束后,栈中的局部变量将消失;对象.Create及New申请的动态空间都是在堆中分配的,在堆中分配的空间不能自动释放,必须用语句显式地释放 一般的子程序的入参及局部变量都放在栈中的,子程序结束后,栈中的局部变量将消失;对象.Create及New申请的动态空间都是在堆中分配的,在堆中分配的空间不能自动释放,必须用语句显式地释放? 写了程序测试了一下:#include "stdafx.h"DWORD WINAPI Thread(void * lParam);int *p;int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ DWORD ID; CreateThread(NULL,0,Thread,NULL,0,&ID); Sleep(3000); //在此设断点,在Debug版会发现p仍然有效 //若p被delete,在debug版本的watch会体现出来 if(p[0]==1) MessageBox(NULL,"p Still Available",""); else MessageBox(NULL,"p has been deleted",""); return 0;}DWORD WINAPI Thread(void * lParam){ p=new int[2]; p[0]=1; return 0;}结果p并没有释放我的理解是p被分配在4GB的虚拟内存空间,属于整个进程所以只有进程结束才自动释放 用new分配内存是在CRT堆上操作。CRT堆只与实例有关,每个实例有一个CRT堆。与线程无关。请注意!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!多线程访问CRT堆一定要LINK多线程CTR库。因为单线程CRT库对堆的访问未作同步,如果多个线程对CRT堆竞争访问会引发灾难!另外实例之间CRT堆的操作,也要注意很多问题。线程堆栈可以自己设定。 To james_razor(蹬三轮的): 说你蹬三轮的没文化,你偏不信。 CreateThread第二个参数dwStackSize是干什么的?给分! To james_razor(蹬三轮的): 说你蹬三轮的没文化,你偏不信。 CreateThread第二个参数dwStackSize是干什么的?给分! 没意思,new 在哪里分配内存是不一定的,因为你可以重载它。。至于默认的new在哪里分配你可以看看VC CRT的源码,最后是用heap alloc的 就20分,谁跟你争!dwStackSize干什么你倒说说看!你要硬说那是线程的资源我也拿你没招!我有没有文化你没资格说! 2 SuperProgMan 说你SuperProgMan没教养,你偏不信! 每个线程有且只有一个线程栈,线程栈初始化为保留的内存(第一页提交),在堆栈增长时会根据需要提交,但是线程栈容量是最初固定好的,无法增长。线程结束线程栈释放。 各位且看,线程栈和资源可以动态的申请和释放的性质相符不相符。分给SuperProgMan,他给我上了一课。2 Kevin_qing(Kevin) 呵呵,版猪都是和事佬。 2 SuperProgMan 说你SuperProgMan没教养,你偏不信! 每个线程有且只有一个线程栈,线程栈初始化为保留的内存(第一页提交),在堆栈增长时会根据需要提交,但是线程栈容量是最初固定好的,无法增长。线程结束线程栈释放。 各位且看,线程栈和资源可以动态的申请和释放的性质相符不相符。分给SuperProgMan,他给我上了一课。2 Kevin_qing(Kevin) 呵呵,版猪都是和事佬。 Kevin_qing(Kevin) 说得对呀 new操作符只是返回一个void指针 指向一段内存系统就认为它的空间满足对象物件的大小需要 之后调用构造函数他的行为是可以重载的 用堆还是栈 自己说得算呀默认的是在堆上诸位大虾们扯远了吧 可是,直接在栈中分配的可能性不大吧。编译器决定了对SS:ESP的操作,每个函数的进栈出栈,局部变量的声明都要对其进行修改。反正我是不敢动的,想多了脑袋都要死机。 可是,直接在栈中分配的可能性不大吧。编译器决定了对SS:ESP的操作,每个函数的进栈出栈,局部变量的声明都要对其进行修改。反正我是不敢动的,多想脑袋都要死机。 仔细看了一下,发现我刚开始没有看清楚题目。可以明确的告诉temp,默认的new是在process的堆里面分配内存的,所以一定要释放。当然你可以想一系列办法,把它变成在stack里面分配(从下往上),不过后果就不敢保证了。 To ALL: 请大家不要信口开河! 用new分配内存是在CRT堆上操作。 CRT堆只与实例有关,每个实例有一个CRT堆。与线程无关。 boodweb(TTT) 兄此言差矣<< if(p[0]==1) MessageBox(NULL,"p Still Available","");<< else MessageBox(NULL,"p has been deleted","");delete并不一定立刻修改存储区的内容吧?只是此块内存可以重新分配了。 子线程里建立记录集。m_pRecordset.CreateInstance("ADODB.Recordset");m_pRecordset->Open();... ...m_pRecordset->Close();m_pRecordset->Release();记录集的存储资源在哪里分配?如果不释放记录集,会怎样? 每个进程只有一个缺省堆!可以有多个私有堆。每个实例有一个CRT堆。(如果用了C库的话)在NT里,堆是建立在虚拟内存的基础上。它是保留的一块内存,。。堆是可以动态增长的。栈也是建立在虚拟内存的基础上。栈的大小是固定。如果你的函数递归层次过多,就会溢出。 2 SuperProgMan: 您指的“大家”也包括我吧,如果不是,那我可就自作多情了,呵呵。 拜托您把“大家”的回复看清楚,没人说new分配内存不是在堆上,而是说可以重载来改变它的动作。也没人说堆与线程相关。 大家说的都是自己学习开发过程中获得的经验,可不是您说的“信口开河”! To 蹬三轮的: CRT堆! 先别吵!子线程里建立的数据库记录集,是在进程的堆里分配空间吗?m_pRecordset.CreateInstance("ADODB.Recordset");... ...m_pRecordset->Release();一定要自己释放吗? CreateInstance==new Release()==delete then you know ``````` 别以为我不知道,CRT:阴极射线管,嘿嘿 CreateInstance==new Release()==delete then you know ```````/*-----------*/这么说是在进程的堆中分配了? 喂,SuperProgMan,要不要修正为阴极射线管堆? invaders(不负少年头) 兄我已经说清楚是在debug版本里自己去试试啊确实是堆 new是全局操作符,在堆里分配内存。在什么地方用都是一样必须要用delete 呵呵,在对线程使用new时,不需要delete释放,否则反而会出错 2 SuperProgMan: 秀逗,懒的理你。 <<呵呵,在对线程使用new时,不需要delete释放,否则反而会出错 什么意思? 没听说过你用我的程序在线程里delete试试,没问题啊 yuxuguang(余旭光)兄是笔误吗? 动态创建的CEdit,SetSel不起作用 如何发布消息取消或者中断复制过程 GetCurrentProcessId()!=0 这是判断的什么? 这样的头儿是不是该离开(散分) 截图程序 CRichEditCtrl头疼的问题 --- 行间距不能设为0? 有好书吗? 象我这样做底层的人还有饭吃吗? 请问在<<深入浅出>>中,cl.exe是个什么命令? VC6.0 在Win8中,单步调试的崩溃问题(F5就没问题) (!!大出血求解)怎样实现矩形框(里面有文字)的拖曳和几个矩形框的连线。希望能详尽解答,谢谢!!!(这已是我能给的最高分了) 多线程的概念问题。
但你用了new以后就不行了,不然就会造成内存泄漏(老师教的)就是这个变量空占着内存但没有指向它的指针了谁都访问不到,因为我还没学操作系统,内部的机制我不大清楚,但我肯定这是必须的。
对于同一个进程的多个线程而言,它们之间是共享同一内存空间的,虽然每个线程都有自己的堆栈,但它们使用同一块堆。你可以把线程理解为一个函数或过程,它可以有自己的局部变量,而用new分配的变量相当于全局变量,可供同一进程的其它线程共享,所以线程退出后,应及时释放,否则这段空间就一直被你占用着。
作 者:Neo2D
所属论坛:Delphi
问题点数:20
回复次数:10
发表时间:2001-5-10 22:31:00
本来该在VC论坛问,但这里人多呀:)
回复贴子:
回复人:colacoca(可口可乐) (2001-5-11 1:25:00) 得3分
堆是先进先出原则
栈是后进先出原则
回复人:BigBen(江南草) (2001-5-11 8:17:00) 得3分
在win32和win16中,堆(heap)是指可供分配的内存,进程中可动态分配。这不同于数据结构中所讲的堆。
回复人:sanjianxia(三剑侠) (2001-5-11 9:05:00) 得0分
两种都可动态分配。
回复人:BCB(:)) (2001-5-11 9:14:00) 得3分
局部变量在栈中分配,
动态申请的变量空间在堆中分配;
回复人:skimwater(掠水惊鸿) (2001-5-11 9:22:00) 得0分
有道理。
回复人:wanwangzhiwang(万王之王) (2001-5-11 9:32:00) 得0分
呵,我对这两个东东不是很了解,当个听众!大家继续!
回复人:cq_xiaolong(fg) (2001-5-11 9:49:00) 得0分
那怎么应用堆跟栈呢?关注!
回复人:maozefa(之源) (2001-5-11 10:20:00) 得5分
在传统的C中堆和栈实际是一块物理内存,堆主要用来动态分配内存,从堆栈内存的低端向上分配;而栈主要用来传递函数参数、返回值和局部参数内存分配,是从堆栈内存的高端向下分配,俗称压栈和出栈。
回复人:Kingron(WinAPI) (2001-5-11 10:32:00) 得1分
看看TStack(堆栈)跟TQueue(队列)类吧。帮助上面有的。
回复人:BCB(:)) (2001-5-11 10:50:00) 得5分
一般的子程序的入参及局部变量都放在栈中的,子程序结束后,栈中的局部变量将消失;
对象.Create及New申请的动态空间都是在堆中分配的,在堆中分配的空间不能自动释放,
必须用语句显式地释放
对象.Create及New申请的动态空间都是在堆中分配的,在堆中分配的空间不能自动释放,
必须用语句显式地释放?
#include "stdafx.h"
DWORD WINAPI Thread(void * lParam);
int *p;
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
DWORD ID;
CreateThread(NULL,0,Thread,NULL,0,&ID);
Sleep(3000); //在此设断点,在Debug版会发现p仍然有效
//若p被delete,在debug版本的watch会体现出来
if(p[0]==1) MessageBox(NULL,"p Still Available","");
else MessageBox(NULL,"p has been deleted","");
return 0;
}DWORD WINAPI Thread(void * lParam)
{
p=new int[2];
p[0]=1;
return 0;
}
结果p并没有释放
我的理解是p被分配在4GB的虚拟内存空间,属于整个进程
所以只有进程结束才自动释放
CRT堆只与实例有关,每个实例有一个CRT堆。与线程无关。请注意!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
多线程访问CRT堆一定要LINK多线程CTR库。
因为单线程CRT库对堆的访问未作同步,如果多个线程对CRT堆竞争访问会引发灾难!另外实例之间CRT堆的操作,也要注意很多问题。线程堆栈可以自己设定。
说你蹬三轮的没文化,你偏不信。
CreateThread第二个参数dwStackSize是干什么的?给分!
说你蹬三轮的没文化,你偏不信。
CreateThread第二个参数dwStackSize是干什么的?给分!
至于默认的new在哪里分配你可以看看VC CRT的源码,最后是用heap alloc的
dwStackSize干什么你倒说说看!
你要硬说那是线程的资源我也拿你没招!
我有没有文化你没资格说!
说你SuperProgMan没教养,你偏不信!
每个线程有且只有一个线程栈,线程栈初始化为保留的内存(第一页提交),在堆栈增长时会根据需要提交,但是线程栈容量是最初固定好的,无法增长。线程结束线程栈释放。
各位且看,线程栈和资源可以动态的申请和释放的性质相符不相符。分给SuperProgMan,他给我上了一课。2 Kevin_qing(Kevin)
呵呵,版猪都是和事佬。
说你SuperProgMan没教养,你偏不信!
每个线程有且只有一个线程栈,线程栈初始化为保留的内存(第一页提交),在堆栈增长时会根据需要提交,但是线程栈容量是最初固定好的,无法增长。线程结束线程栈释放。
各位且看,线程栈和资源可以动态的申请和释放的性质相符不相符。分给SuperProgMan,他给我上了一课。2 Kevin_qing(Kevin)
呵呵,版猪都是和事佬。
说得对呀 new操作符只是返回一个void指针 指向一段内存
系统就认为它的空间满足对象物件的大小需要 之后调用构造函数
他的行为是可以重载的 用堆还是栈 自己说得算呀
默认的是在堆上
诸位大虾们扯远了吧
编译器决定了对SS:ESP的操作,每个函数的进栈出栈,局部变量的声明都要对其进行修改。
反正我是不敢动的,想多了脑袋都要死机。
编译器决定了对SS:ESP的操作,每个函数的进栈出栈,局部变量的声明都要对其进行修改。
反正我是不敢动的,多想脑袋都要死机。
可以明确的告诉temp,默认的new是在process的堆里面分配内存的,所以一定要释放。当然你可以想一系列办法,把它变成在stack里面分配(从下往上),不过后果就不敢保证了。
请大家不要信口开河! 用new分配内存是在CRT堆上操作。
CRT堆只与实例有关,每个实例有一个CRT堆。与线程无关。
<< else MessageBox(NULL,"p has been deleted","");
delete并不一定立刻修改存储区的内容吧?只是此块内存可以重新分配了。
m_pRecordset->Open();... ...m_pRecordset->Close();
m_pRecordset->Release();
记录集的存储资源在哪里分配?
如果不释放记录集,会怎样?
可以有多个私有堆。
每个实例有一个CRT堆。(如果用了C库的话)在NT里,堆是建立在虚拟内存的基础上。
它是保留的一块内存,。。
堆是可以动态增长的。栈也是建立在虚拟内存的基础上。
栈的大小是固定。
如果你的函数递归层次过多,就会溢出。
您指的“大家”也包括我吧,如果不是,那我可就自作多情了,呵呵。
拜托您把“大家”的回复看清楚,没人说new分配内存不是在堆上,而是说可以重载来
改变它的动作。也没人说堆与线程相关。
大家说的都是自己学习开发过程中获得的经验,可不是您说的“信口开河”!
CRT堆!
Release()==delete
then you know ```````
Release()==delete
then you know ```````/*-----------*/这么说是在进程的堆中分配了?
我已经说清楚是在debug版本里
自己去试试啊确实是堆
在什么地方用都是一样
必须要用delete
你用我的程序在线程里delete试试,没问题啊