一个C/C++程序内存分配形式

一:一个C/C++程序编译之后在内存中一般分为五个部分

1. 程序代码区:程序代码区主要用来存放程序执行代码,包括类成员函数、全局函数、静态函数等其它函数的代码。这部分内存区域的大小在程序运行前就已经确定了,并且内存通常是只读的。一般程序代码区是可以被共享的

2. 常量区:用来存放常量的内存区域,程序结束后由操作系统收回

3. 全局数据区(静态存储区):存放全局变量和静态变量,程序结束后由操作系统收回。

    全局变量、静态全局变量、静态局部变量都是在静态存储区分配空间的。

4. 堆区:堆用于存放程序运行中动态分配的内存段,它的大小不是固定的,可以动态的扩张和缩减。

    当进程调用new或malloc申请内存空间的时候,堆被扩张;当使用delete或free释放内存空间的时候,堆被缩减。

    堆一般由程序员手动分配和释放,如果没有释放则会在程序结束的时候由操作系统收回。

    堆的内存分配机制如下:操作系统有一个专门用来存储空闲内存地址的链表,链表每个结点表示一块空闲内存地址空间。当程序收到new或malloc申请时,就去查找这个链表直到找到一个结点的内存空间大于所申请的内存空间,将这个结点从链表中删除并将内存分配给程序,如果有剩余的内存空间则继续放入到链表中使用。

    堆区不是连续的内存空间因为系统用链表来存储空闲内存地址,堆的内存空间相对较大,在windows下堆申请的空间一般超过2G。

5. 栈区:栈区主要用来存储程序临时创建的局部变量,包括函数体内的局部变量、函数参数等。(但是不包括静态局部变量因为所有的静态变量存放在全局数据区)

   栈由编译器自动分配和释放,操作形式类似数据结构的栈,效率比较高,但是栈能够分配的大小是固定的一般比较小。  

   栈是一块连续的内存区域,栈顶的地址和栈的容量是预先规定好的,windows下栈的大小是2M。

二:堆区是由低地址向高地址生长,栈是由高地址向低地址生长

举例:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

int global = 5; //全局数据区
static int value = 3; //全局数据区

int main(){
	int a; //栈区
	char str[] = "abc"; //str存放在栈区
	char *p = str; //栈区
	static int c = 0; //全局数据区
	char *p1;
	p1 = (char *)malloc(5*sizeof(char)); //堆区
	p1 = "1234"; //"1234"存放在常量区
	return 0;
}

三:内存泄露

1. 堆是动态分配内存的,可以分配比较大的内存空间,因此使用不好容易造成内存泄露和内存碎片

2. 内存泄露一般是指堆内存的泄露,指的是由于疏忽或错误造成程序未能释放已经不再使用的内存空间,造成这些内存空间不受控制造成内存浪费

时间: 2024-08-01 12:47:07

一个C/C++程序内存分配形式的相关文章

为C++标准库容器写自己的内存分配程序

根据sgi 的STL源码的二级分配算法改写的内存池分配程序,只要稍微修改就可以实现共享内存方式管理,使用C++标准库容器中的map,set,multimap,multiset测试通过,vector测试通不过,原因是在内存回收的时候考虑的比较简单,vector每次分配内存个数不固定,回收也不固定,这样的话,程序还需要继续完善. 内存池管理程序源码如下: #ifndef MY_ALLOCATOR_H_#define MY_ALLOCATOR_H_#include "stdafx.h"#in

降低.NET应用程序内存占用的实践和总结

最近一周比较忙,主要的工作内容是在做一个叫"键盘精灵"的东西,简单来讲就是将很多数据放到内存中,对这些数据进行快速检索,然后找出根据输入条件最匹配的10条记录并予以展示.具体和下面两款炒股软件的相关功能类似: 数据以文本形式存在文件中,且数据量较大,有近20万条,每一条记录有几个字段,以分隔符分割.当时使用的是6万条记录的测试数据,文本文件将近10M,这个模块加载到内存并建立缓存之后,大概会占用将近70-80M的内存.自我接手以后,主要的任务就是降低内存消耗和提高匹配效率. 一.避免创

减少.NET应用程序内存占用的一则实践

最近一周比较忙,主要的工作内容是在做一个叫"键盘精灵"的东西,简单来讲就是将很多数据放到内存中,对这些数据进行快速检索,然后找出根据输入条件最匹配的10条记录并予以展示.具体和下面两款炒股软件的相关功能类似: 数据以文本形式存在文件中,且数据量较大,有近20万条,每一条记录有几个字段,以分隔符分割.当时使用的是6万条记录的测试数据,文本文件将近 10M,这个模块加载到内存并建立缓存之后,大概会占用将近70-80M的内存.自我接手以后,主要的任务就是降低内存消耗和提高匹配效率. 一.避免

对C++程序内存管理的精雕细琢

应用程序分配内存的方法,对程序的执行性能有着深刻的影响.目前,通用的内存分配方法本质上已非常高效,但仍有改进的空间. 内存分配,不可一层不变 今天,对绝大多数程序来说,通用的内存分配方法--此处指代分配算符(Allocator:即malloc或new),已达到了理想的速度及满足了低碎片率的要求,然而,在内存分配领域,一丁点的信息都值得探讨很久,某些特定程序关于分配模式的信息,将有助于实现专门的分配算符,可显著地提高大多数高性能要求程序的性能底线.有时,当通用内存分配算符平均耗费几百个时钟周期时,

linux环境内存分配原理 mallocinfo【转】

转自:http://www.cnblogs.com/dongzhiquan/p/5621906.html Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和free是如何分配和释放内存?如何查看堆内内存的碎片情况?既然堆内内存brk和sbrk不能直接释放,为什么不全部使用 mmap 来分配,munmap直接释放呢 ? Linux 的虚拟内存管理有几个关键概念: 1.每个进程都有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址: 2.虚拟地址可通过

关于Java 数组内存分配一点认识

 可能Java 数组大家都很熟悉,最近我遇到了一个关于Java 数组内存分配的问题.         呵呵.突然就发现许多书上"基本数据类型存储在栈内存当中,对象则保存在堆内存"这句话完全是错误的.下面是个简单的例子代码: public class Test { public static void main(String[] argv) { // 静态初始化数组 String[] names = { "Michael", "Orson", &q

找出Java程序内存溢出的元凶

我曾经在刚入行的时候做过一个小的swing程序,用到了java SE,swing,Thread等东东,当初经验少 也没有做过严格的性能测试,布到生产环境用了一段时间后发现那个小程序有时候会抛 java.lang.OutofMemoryError异常,就是java的内存溢出.当时也上网查了不少资料,试过一些办法,代 码也稍微做了些优化,但是有一个问题我始终是找不到解决的方案 - 不知为什么子窗体关闭后java的垃 圾回收机制无法回收其资源,因为这个Java程序可能要经常开关一些子窗体,那么这些子窗

基于Java 数组内存分配的相关问题_java

可能Java 数组大家都很熟悉,最近我遇到了一个关于Java 数组内存分配的问题.呵呵.突然就发现许多书上"基本数据类型存储在栈内存当中,对象则保存在堆内存"这句话完全是错误的.下面是个简单的例子代码: 复制代码 代码如下: public class Test {    public static void main(String[] argv) {// 静态初始化数组String[] names = { "Michael", "Orson",

class-同一个程序代码,不同的地方new同一个类,内存分配大小不一样

问题描述 同一个程序代码,不同的地方new同一个类,内存分配大小不一样 同样的写法 CLASS A: A* a1=new A: A *a2=new A: 两个语句在代码不同的地方执行而已 new操作符没重载 sizeof(A)得出来的结果是4760, 有人遇到过类似的问题吗,什么原因导致这样的问题, 完全没头绪!!!!!!!!! 解决方案 会不会是内存的对齐产生的问题. 解决方案二: 编译器debug优化关了没