标签:
it |
分类: 技术/开发(原创/转载) |
一、预备知识—程序的内存分配
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)—由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2、堆区(heap)— 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。
二、例子程序
这是一个前辈写的,非常详细
//main.cpp
inta = 0; 全局初始化区
char*p1; 全局未初始化区
main()
{
int b; // 栈
char s[] = "abc"; //
栈
char *p2; // 栈
char *p3 = "123456"; //
123456\0在常量区,p3在栈上。
static int c =0; //
全局(静态)初始化区
p1 = (char *)malloc(10);
p2 = (char *)malloc(20);
//
分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); //
123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}
一个由c/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)—
2、堆区(heap)
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,
4、文字常量区
5、程序代码区—存放函数体的二进制代码。
二、例子程序
这是一个前辈写的,非常详细
//main.cpp
int
char
main()
{
}
三、堆和栈的理论知识
3.1申请方式
stack:
heap:
如p1
在C++中用new运算符
如p2
但是注意p1、p2本身是在栈中的。
3.2 申请后系统的响应
3.3申请大小的限制
3.4申请效率的比较:
3.5堆和栈中的存储内容
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地址,也就是主函数中的下一条指令,程序由该点继续运行。
3.6存取效率的比较
char
char
aaaaaaaaaaa是在运行时刻赋值的;
而bbbbbbbbbbb是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
比如:
#include
void
{
}
对应的汇编代码
10:
00401067
0040106A
11:
0040106D
00401070
00401073
第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。
3.7小结:
堆和栈的区别可以用如下的比喻来看出:
使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。
使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。
四、栈的区别主要分
系统方面的堆和栈,如上面说的那些,不多说了。
就是数据结构方面的堆和栈,这些都是不同的概念。这里的堆实际上指的就是(满足堆性质的)优先队列的一种数据结构,第1个元素有最高的优先权;栈实际上就是满足先进后出的性质的数学或数据结构。
虽然堆栈,堆栈的说法是连起来叫,但是他们还是有很大区别的,连着叫只是由于历史的原因。