您的位置:首页 > 其它

【内存分配系列】之进程内部内存分配(内存篇 第2节)

2009-11-23 13:42 316 查看
上一节大致讲了下系统是如何为进程分配内存。那么一个进程得到了这4G空间后该怎么办呢?程序员可以使用全部内存么?答案是否定的。

WINDOWS操作系统将地址范围4M-2G划分为用户地址空间,其余空间保留给系统之用或系统预留空间。还有一点请注意。每个进程分配时,内存地址都是从0~0xFFFFFFFF(4G)。A进程地址0X400000(4M)映射了可执行文件,而B进程的地址0X400000(4M)也映射了可执行文件。当然A和B映射的物理内存地址是不同的。这个差异由MMU来控制。至于进程在物理内存中的边界问题,很复杂,我没搞懂,不便发表言论,唯恐别人笑我SB,反正我知道是MMU提供的防止进程内存越界的技术。

既然内存也分配好了,用户空间也划好了,那么进程内部怎么规划这些空间呢?

C/C++编译的程序内存空间分为这么几种:

1、栈区(stack)——由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

2、堆区(heap)——一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式类似于链表。

3、全局区(静态区 static)——全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。

4、文字常量区——常量字符串就是放在这里的。 程序结束后由系统释放

5、程序代码区——存放函数体的二进制代码。

引用网上的一个例子。

//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放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。

}

我只讲个大概,函数的一些值类型数据都由系统分配在栈区。而堆区是由程序员自己分配。例如,C中,用malloc()函数进行内存分配。而释放用free()函数。不过看网上据说是不可以释放栈区内存。而C++中,可以用int *p;p=new int;来分配内存。至于释放,可以用delete p;我在考虑,那我删掉的只是个指针啊,嗯,似乎是这样的。那么我们有理由相信一点,系统只是用一个链表记录未被系统指向的内存,即所谓的空闲内存。但是如果内存空间被赋值了,即使你删了指针,那么内存的内容仍然没变。所以申请一块内存后,请先清空内存再使用。呵呵......

通过这一节的介绍,你可能已经对进程内部如果规划内存有了一定了解,也知道了我们的一些数据具体放在那里了。我们每一个进程内部都是按上面这样分配的哦!呵呵,不要搞混。

结构体作为一种重要的值类型,它的内存是如何分配的呢,它跟类又有哪些差别呢,请看下节:《【内存分配系列】之结构体和类内存分配(内存篇 第3节)》。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐