C++内存分配方式及内存空间划分

一、内存分配方式:,
 1、 全局/静态/常量存储区,是在程序编译时就已经分配好的,在整个运行期间都存在,如全局变量、静态局部变量、静态全局变量、常量。
 2、 栈上分配,由编译器在需要的时候分配,在不需要的时候自动清除,局部变量、函数参数就是从这分配的,但分配的内存容易有限。对于栈来讲,它的生长方式是向下的,是向着内存地址减小的方向增长。在vc编译器中,默认的栈大小是1M,可自己修改。
 3、 堆上分配,也称动态分配,由new,malloc分配内存,他们的释放编译器不管,用delete,free来释放的内存。如果没有释放掉,程序结束后,操作系统会自动回收。对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;一般来讲,在32为系统下面,堆内存可达到4G的空间。(注:堆是操作系统维护的一块内存,它提供了动态分配的功能,而自由存储是C++中通过new与delete动态分配和释放对象的抽象概念。基本上,所有的C++编译器默认使用堆来实现自由存储,但也可以不用堆实现。)

二、内存空间划分:
1 栈区:栈中保存基本数据类型的变量和自定义对象的引用(不是对象,对象本身放堆区),被执行的方法的也是pull到栈中,当方法执行完后再push出栈。比如局部变量
2 堆区:Test t = new Test(); 对象的引用t存在栈中,new Test()对象在堆中。堆中存储的都是对象,每个对象包含一个与之对应的class信息。
3 代码区:函数、类中的方法,存在代码区。
4 全局数据区:静态变量、全局变量、常量。类的static变量是全局的,是类的所有对象都能访问的,非static变量是私有的,是每个对象独有的特有的,并且只有非static方法才可以访问。

堆和栈的主要区别由以下几点:
1、管理方式不同;
2、空间大小不同;
3、能否产生碎片不同;
4、生长方向不同;
5、分配方式不同;
6、分配效率不同;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基本分页存储管理方式下,内存被分为若干固定大小的页框,而进程所需的空间被划分为若干个大小相等的页面,每个进程有自己的页表来描述它所拥有的页面。在这种情况下,内存的分配和回收可以通过以下方式实现: 1. 内存分配 首先,需要一个数据结构来记录内存中所有的页框的使用情况,可以使用一个位图来表示。每个位对应一个页框,如果该页框已经被分配给进程,则相应的位被标记为1,否则为0。当进程请求内存时,需要遍历位图,找到第一个连续的空闲页框,将它们标记为已分配,并返回它们的起始地址作为分配的内存空间。 2. 内存回收 当进程结束时,需要将其占用的内存空间释放回来。这可以通过清除页表中相应的页面条目以及标记位图中相应的位来完成。具体来说,可以遍历进程的页表,将其中所有指向已分配页面的条目清除,然后在位图中将对应的位清零即可。 下面是C++代码实现: ```c++ #include <iostream> #include <cstring> using namespace std; const int PAGE_SIZE = 4; // 页面大小 const int NUM_PAGES = 16; // 内存中页面数 const int NUM_FRAMES = 4; // 内存中页框数 struct PageTableEntry { int frameNum; // 页框号 bool valid; // 是否有效 }; class MemoryManager { public: MemoryManager() { memset(bitmap, 0, sizeof(bitmap)); // 初始化位图 for (int i = 0; i < NUM_FRAMES; i++) { bitmap[i] = false; } } void* allocate(int numPages) { if (numPages <= 0 || numPages > NUM_PAGES) { return nullptr; // 分配失败 } int start = -1; for (int i = 0; i < NUM_FRAMES; i++) { if (bitmap[i] == false) { if (start == -1) { start = i; } if (i - start + 1 == numPages) { break; } } else { start = -1; } } if (start == -1) { return nullptr; // 分配失败 } for (int i = start; i < start + numPages; i++) { bitmap[i] = true; // 标记为已分配 } return (void*)(start * PAGE_SIZE); // 返回起始地址 } void deallocate(PageTableEntry* pageTable) { for (int i = 0; i < NUM_PAGES; i++) { if (pageTable[i].valid) { int frameNum = pageTable[i].frameNum; bitmap[frameNum] = false; // 标记为未分配 pageTable[i].valid = false; // 清除页表条目 } } } private: bool bitmap[NUM_FRAMES]; }; int main() { MemoryManager memMgr; PageTableEntry pageTable[NUM_PAGES]; void* ptr1 = memMgr.allocate(2); // 分配2个页面 if (ptr1 == nullptr) { cout << "Allocation failed." << endl; return 0; } for (int i = 0; i < 2; i++) { pageTable[(int)ptr1 / PAGE_SIZE + i].frameNum = (int)ptr1 / PAGE_SIZE + i; pageTable[(int)ptr1 / PAGE_SIZE + i].valid = true; // 填充页表 } void* ptr2 = memMgr.allocate(3); // 分配3个页面 if (ptr2 == nullptr) { cout << "Allocation failed." << endl; return 0; } for (int i = 0; i < 3; i++) { pageTable[(int)ptr2 / PAGE_SIZE + i].frameNum = (int)ptr2 / PAGE_SIZE + i; pageTable[(int)ptr2 / PAGE_SIZE + i].valid = true; // 填充页表 } memMgr.deallocate(pageTable); // 释放内存 return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值