c语言中 堆怎么理解?
1、c语言中,局部变量不能超出函数的范围。而全局变量在编译期就已经确定了,缺乏动态性。这是引入堆这个概念的原因吗?2、如果在函数体中出现char*p=(char*)mal...
1、c语言中,局部变量不能超出函数的范围。而全局变量在编译期就已经确定了,缺乏动态性。这是引入堆这个概念的原因吗?
2、如果在函数体中出现 char *p = (char*)malloc(1000); p还是超不出函数的范围。
那到底为什么引入堆的概念?没有堆行不行?有了堆有哪些好处?
(学SSH出身的,我快给搞崩溃了)
各位大神麻烦说的详细点。 谢谢! 展开
2、如果在函数体中出现 char *p = (char*)malloc(1000); p还是超不出函数的范围。
那到底为什么引入堆的概念?没有堆行不行?有了堆有哪些好处?
(学SSH出身的,我快给搞崩溃了)
各位大神麻烦说的详细点。 谢谢! 展开
4个回答
展开全部
c中代码在代码段,数据在数琚段,局部变量在堆栈中,除了这些已经明确安排好的空间,剩余空间称为自由空间,要利用这些空间可以通过内存分配函数,动态分配,这部分空间称为堆空间!堆空间相比栈空间是非常大的,栈空间是非常有限的windows下32位程序,缺省约为1M而每个程序的地址空间为4G,堆空间使用1~2G内存是不成问题的。
至于p那个指针本身是局部变量,p所指内存在堆上出了函数也是可以用的,必须能够传递出去才行,p自己只能在函数内部使用!传递出去的指针必须在适当的时候释放,否则会产生内存泄漏!
1)这么理解似平不是问题,不过太肤浅;
2)由于各种编程语言(包括c,c )不能(也不允许)直接访问内存,和cpu各寄存器,要通过标志符(就是一个名字)来访问它们,这就牵扯到名字的作用域问题了!而内存,寄存器这些东西本来就在和语言无关,只和该语言如何使用有关,通过名字,我们可以更清晰的理解代码的意图,可以更好的安排代码,所以各种语言,通过名字来使用内存和寄存器!这样名字就和内存,寄存器这种实际存在的东西联系到一起了!变量是最经常使用的一种名字了!对c,这种语言自动变量在堆上,只有函数内部甚至内部的一对大括号内可用(即变量名可见,如果变量的相关内容,如变量值,变量地址,传递出去,外部也是可以使用的,当然同一程序的内部变量地址就不要传递了!同样参数和返回值也不要把自动变量地址传递出去,因为已经过期,有可能被别的东西占用了,使用会么错的,而动态分配的内存其实属于全局性质的,传递出去是没问题的,只要能够及时释放就行,那就是无名全局数据,可以通过有名变量(指针)来使用,因为没有名字所以不能直接促使用,因为是全局的所以可以任意传递,因为要管理的,所以用完要释放!因为无名,所以只能间接引用!
至于p那个指针本身是局部变量,p所指内存在堆上出了函数也是可以用的,必须能够传递出去才行,p自己只能在函数内部使用!传递出去的指针必须在适当的时候释放,否则会产生内存泄漏!
1)这么理解似平不是问题,不过太肤浅;
2)由于各种编程语言(包括c,c )不能(也不允许)直接访问内存,和cpu各寄存器,要通过标志符(就是一个名字)来访问它们,这就牵扯到名字的作用域问题了!而内存,寄存器这些东西本来就在和语言无关,只和该语言如何使用有关,通过名字,我们可以更清晰的理解代码的意图,可以更好的安排代码,所以各种语言,通过名字来使用内存和寄存器!这样名字就和内存,寄存器这种实际存在的东西联系到一起了!变量是最经常使用的一种名字了!对c,这种语言自动变量在堆上,只有函数内部甚至内部的一对大括号内可用(即变量名可见,如果变量的相关内容,如变量值,变量地址,传递出去,外部也是可以使用的,当然同一程序的内部变量地址就不要传递了!同样参数和返回值也不要把自动变量地址传递出去,因为已经过期,有可能被别的东西占用了,使用会么错的,而动态分配的内存其实属于全局性质的,传递出去是没问题的,只要能够及时释放就行,那就是无名全局数据,可以通过有名变量(指针)来使用,因为没有名字所以不能直接促使用,因为是全局的所以可以任意传递,因为要管理的,所以用完要释放!因为无名,所以只能间接引用!
展开全部
堆主要区别于栈,栈有后进先出的特点,堆则没有。栈好像是枪的弹夹,向里压入子弹,最后压入的子弹最先被射出,而最先压入的子弹则最后被射出;堆好像一盘菜,你下筷子夹菜不用考虑菜的摆放位置,夹到哪个吃哪个。
char *p = (char*)malloc(1000);
在程序默认堆中申请1000个字节的内存,把这一段的首地址赋值给p,当p所在的函数结束后,p作为局部变量将失去意义,也不可再被访问到。但是申请到的1000字节却还在,不会被释放,除非写代码显式释放
char *p = (char*)malloc(1000);
在程序默认堆中申请1000个字节的内存,把这一段的首地址赋值给p,当p所在的函数结束后,p作为局部变量将失去意义,也不可再被访问到。但是申请到的1000字节却还在,不会被释放,除非写代码显式释放
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
1.基本上可以这样理解
2.p这个变量是被释放了,但是它存放的值可以被传出来给其他函数,例如:
char * get()
{
char *p = (char*)malloc(1000);//p中存放了动态开辟的内存的首地址
return p;//把p存放的地址值返回给调用它的函数
}
int f()
{
int i = 0;
return i;
}
int main(void)
{
int x = f();//f函数中的i在f运行完后也会被释放啊,那你认为这里的x会得到什么值呢?
char *a = get();//a获得了get函数返回的那个地址值,也就是说,a指向了那段内存,这时,用a就可以使用get函数中开辟的那段内存
*a = 'c';//往申请的那段内存放入值,和char *a;*a='c';做比较,后者这样肯定是会报错的,因为后面这个指针指向哪里都不知道
free(a);//释放在get函数中申请的那段内存
return 0;
}
2.p这个变量是被释放了,但是它存放的值可以被传出来给其他函数,例如:
char * get()
{
char *p = (char*)malloc(1000);//p中存放了动态开辟的内存的首地址
return p;//把p存放的地址值返回给调用它的函数
}
int f()
{
int i = 0;
return i;
}
int main(void)
{
int x = f();//f函数中的i在f运行完后也会被释放啊,那你认为这里的x会得到什么值呢?
char *a = get();//a获得了get函数返回的那个地址值,也就是说,a指向了那段内存,这时,用a就可以使用get函数中开辟的那段内存
*a = 'c';//往申请的那段内存放入值,和char *a;*a='c';做比较,后者这样肯定是会报错的,因为后面这个指针指向哪里都不知道
free(a);//释放在get函数中申请的那段内存
return 0;
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
(个人见解)栈存取速度快,但其空间是有限的,所以要有堆来补充,另外,堆能在需要的时候开辟,不需要的时候及时的释放,从而能达到内存的最合理使用
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询