您的位置:首页 > 其它

静态分配和动态分配

2015-09-05 20:03 246 查看
静态分配和动态分配
在讲述这个之前我们分享一段程序,从这个程序中我们来思考下为什么,类似的程序最后的输出结果不一样:
char* stackMalloc()
{
	char str[] = "yelllo";
	return str;
}
char* heapMalloc()
{
	char *str =  "helllo";//
	return str;
}
int main()
{
	char *str = heapMalloc(); 
	int i = 0;
	while(str[i] != '\0')printf("字符串中的元素%c\n", str[i++]);
    return 0;
}


调用第一个函数时,str指向的那块内存在函数返回时,被系统释放了。返回后的str什么都没有。最后输出的都是乱的。而调用第二个函数时,str指向的那块内存在函数返回时,竟然没被系统释放,最后在主函数中能够把str指向的内存里面的数据输出来。为什么第二个函数返回时,str指向的内存区域没被系统释放??为此下面引出本文我们要讲的主题—静态分配和动态分配。

静态分配-静态分配是编译器完成的,不能由程序员自动分配和释放。如局部变量的分配。
动态分配-动态分配我们可以在函数中任何时候定义分配并释放,并且由程序员分配释放,系统不会自动释放。动态分配的数据空间存放在堆中。上面的第二个函数中,char *str = "helllo"是在堆中分配内存,所以函数返回时,内存不释放。

c/c++程序占有的内存空间逻辑上分为四个部分:1、静态数据区 2、动态数据区 3、代码区 4、文字常量区

1、静态数据区-静态数据区也称之为全局区,全局变量和静态变量分配在静态数据区。初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 程序结束后由系统释放。

2、动态数据区-动态数据区包括栈区和堆。栈(stack)和堆(heap)是两种不同的动态数据区,栈是一种线性结构,堆是一种链式结构。本地变量分配在动态数据区。下面对里面的栈区和堆区分别说明:

(1)栈区(stack)
由编译器自动分配释放 ,存放函数的参数值,局部变量的值等,内存的分配是连续的,那么就把它想成数组,它的内存分配是连续分配的,即所分配的内存是在一块连续的内存区域内.当我们声明变量时,那么编译器会自动接着当前栈区的结尾来分配内存。栈是从高地址向低地址增长的。
(2)堆区(heap)
一般由程序员分配释放, 若程序员不释放,程序结束时可能由操作系统回收。类似于链表,在内存中的分布不是连续的,它们是不同区域的内存块通过指针链接起来的.一旦某一节点从链中断开,我们要人为的把所断开的节点从内存中释放。堆是从低地址向高地址增长的。
注意:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。栈的动态分配和堆不同,它的动态分配是由编译器进行释放,无需我们手工实现。

3、代码区-存放函数体的二进制代码。

4、文字常量区-常量字符串存储在这里,程序结束后由系统释放。

注意:在栈上所申请的内存空间,当我们出了变量所在的作用域后,系统会自动回收这些空间,而在堆上申请的空间,当出了相应的作用域以后,我们需要自己释放所申请的内存空间,如果我们不及时对这些空间进行释放,那么内存中的内存碎片就越来越多,从而我们的实际内存空间也就会变的越来越少。

下面给出C中的代码内存布局:



从上面我们可以明显看出栈是从高地址向低地址增长,堆是从低地址向高地址增长。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: