标签:
1.1 操作系统中的栈和堆
注:这里所说的堆和栈与数据结构中的堆和栈不是一回事。
我们先来看看一个由C/C++/OBJC编译的程序占用内存分布的结构:
栈区(stack):由系统自动分配,一般存放函数参数值、局部变量的值等。由编译器自动创建与释放。其操作方式类似于数据结构中的栈,即后进先出、先进后出的原则。
例如:在函数中申明一个局部变量int b;系统自动在栈中为b开辟空间。
堆区(heap):一般由程序员申请并指明大小,最终也由程序员释放。如果程序员不释放,程序结束时可能会由OS回收。对于堆区的管理是采用链表式管理的,操作系统有一个记录空闲内存地址的链表,当接收到程序分配内存的申请时,操作系统就会遍历该链表,遍历到一个记录的内存地址大于申请内存的链表节点,并将该节点从该链表中删除,然后将该节点记录的内存地址分配给程序。
例如:在C中malloc函数
1
2
|
char p1; p1 = (char )malloc(10); |
但是p1本身是在栈中的。
链表:是一种常见的基础数据结构,一般分为单向链表、双向链表、循环链表。以下为单向链表的结构图:
单向链表是链表中最简单的一种,它包含两个区域,一个信息域和一个指针域。信息域保存或显示关于节点的信息,指针域储存下一个节点的地址。
上述的空闲内存地址链表的信息域保存的就是空闲内存的地址。
全局区/静态区:顾名思义,全局变量和静态变量存储在这个区域。只不过初始化的全局变量和静态变量存储在一块,未初始化的全局变量和静态变量存储在一块。程序结束后由系统释放。
文字常量区:这个区域主要存储字符串常量。程序结束后由系统释放。
程序代码区:这个区域主要存放函数体的二进制代码。
下面举一个前辈写的例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
//main.cpp int a = 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在常量区,这个函数的作用是将"123456" 这串字符串复制一份放在p1申请的10个字节的堆区域中。 // p3指向的"123456"与这里的"123456"可能会被编译器优化成一个地址。 } |
strcpy函数
原型声明:extern char *strcpy(char* dest, const char *src);
功能:把从src地址开始且含有NULL结束符的字符串复制到以dest开始的地址空间。
标签:
原文地址:http://www.cnblogs.com/shizhili/p/4532421.html