内存分区模型

16 篇文章 4 订阅

内存分区模型

C++程序在执行时,将内存大方向划分为4个区域

代码区∶存放函数体的二进制代码,由操作系统进行管理的

全局区∶存放全局变量和静态变量以及常量

栈区∶由编译器自动分配释放,存放函数的参数值,局部变量等

堆区∶由程序员分配和释放,若程序员不释放,程序结束时由操作系统回收

内存四区意义:

不同区域存放的数据,赋予不同的生命周期,给我们更大的灵活编程

程序运行前:

在程序编译后,生成了exe可执行程序,未执行该程序前分为两个区域

代码区:存放CPU 执行的机器指令

代码区是共享的,共享的目的是对于频繁被执行的程序.只需要在内存中有一份代码即可代码区是只读的,使其只读的原因是防止程序意外地修改了它的指令

全局区:

全局变量和静态变量存放在此.

全局区还包含了常量区,字符串常量和其他常量也存放在此.该区域的数据如果不手动释放,在程序结束后由操作系统释放

看个例子:

#include <iostream>

using namespace std;

//全局变量

int g_a = 10;

int g_b = 20;

//全局常量

const int c_g_a = 10;

const int c_g_b = 10;

int main0101()

{

    //局部变量

    int a = 10;

    int b = 20;

    //静态变量

    static int s_a = 10;

    static int s_b = 20;

    //局部常量

    const int c_l_a = 10;

    const int c_l_b = 10;

    //打印地址

    cout << "局部变量a地址为:" << (int)&a << endl;

    cout << "局部变量b地址为:" << (int)&b << endl;

    cout << "全局变量g_a地址为:" << (int)&g_a << endl;

    cout << "全局变量g_b地址为:" << (int)&g_b << endl;

    cout << "静态变量s_a地址为:" << (int)&s_a << endl;

    cout << "静态变量s_b地址为:" << (int)&s_b << endl;

    cout << "全局常量c_g_a地址为:" << (int)&c_g_a << endl;

    cout << "全局常量c_g_b地址为:" << (int)&c_g_b << endl;

    cout << "字符串常量地址为:" << (int)&"Hello" << endl;

    cout << "字符串常量地址为:" << (int)&"World" << endl;

    cout << "局部常量c_l_a地址为:" << (int)&c_l_a << endl;

    cout << "局部常量c_l_b地址为:" << (int)&c_l_b << endl;

    return EXIT_SUCCESS;

}

总结:

C++中在程序运行前分为全局区和代码区 代码区特点是共享和只读

全局区中存放全局变量、静态变量、常量

常量区中存放 const修饰的全局常量 和 字符串常量

程序运行后:

栈区:

由编译器自动分配释放, 存放函数的参数值,局部变量等

注意事项:不要返回局部变量的地址栈区开辟的数据由编译器自动释放

堆区:

由程序员分配释放,若程序员不释放,程序结束时由操作系统回收 在C++中主要利用new在堆区开辟内存

总结:

堆区数据由程序员管理开辟和释放

在C++中,堆区数据利用new关键字进行开辟内存

举例:

#include <iostream>

using namespace std;

int* func()

{

    int a = 10;

    return &a;

}

int* func2()

{

    int* b = new int(20);

    return b;

}

int main()

{

    int* p = func();

    cout << *p << endl;

    cout << *p << endl;

    //两次结果是不一致的

    int* q = func2();

    cout << *q << endl;

    delete q;

    //cout << *q << endl;

    return EXIT_SUCCESS;

}

这里不放截图了,请读者自己去试

new、delete操作符

C++中利用new操作符在堆区开辟数据

堆区开辟的数据,由程序员手动开辟,手动释放,释放利用操作符 delete

new:

语法:new 数据类型

利用new创建的数据,会返回该数据对应的类型的指针

C语言中堆区内存分配和释放

1)malloc()

#include <stdlib.h>

void *malloc(size_t size);

功能:在内存的动态存储区(堆区)中分配一块长度为size字节的连续区域,用来存放类型说明符指定的类型。分配 的内存空间内容不确定,一般使用memset初始化。

参数:

size:需要分配内存大小(单位:字节) 返回值:

成功:分配空间的起始地址 失败:NULL

C语言中堆区内存分配和释放

2)free()

#include <stdlib.h>

void free(void *ptr);

功能:释放ptr所指向的一块内存空间,ptr是一个任意类型的指针变量,指向被释放区域的首地址。对同一内存空 间多次释放会出错。

参数:

ptr:需要释放空间的首地址,被释放区应是由malloc函数所分配的区域。 返回值:无

C语言常用内存操作函数

1) memset() //仅能填0和1

#include <string.h>

void *memset(void *s, int c, size_t n);

功能:将s的内存区域的前n个字节以参数c填入 参数:

s:需要操作内存s的首地址

c:填充的字符,c虽然参数为int,但必须是unsigned char , 范围为0~255 n:指定需要设置的大小

返回值:s的首地址

2) memcpy()

#include <string.h>

void *memcpy(void *dest, const void *src, size_t n);

功能:拷贝src所指的内存内容的前n个字节到dest所值的内存地址上。 参数:

dest:目的内存首地址

src:源内存首地址,注意:dest和src所指的内存空间不可重叠,可能会导致程序报错 n:需要拷贝的字节数

返回值:dest的首地址

3) memmove()

memmove()功能用法和memcpy()一样,区别在于:dest和src所指的内存空间重叠时,memmove()仍然能处理, 不过执行效率比memcpy()低些。

4) memcmp()

#include <string.h>

int memcmp(const void *s1, const void *s2, size_t n);

功能:比较s1和s2所指向内存区域的前n个字节 参数:

s1:内存首地址1 s2:内存首地址2 n:需比较的前n个字节

返回值:

相等:=0 大于:>0 小于:<0

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值