【C\C++】C\C++内存管理

目录

一、C\C++内存分配

1、栈区

2、堆区

3、全局(静态)区

4、常量区

5、代码段

二、C语言内存管理方式

1、malloc

2、calloc

3、relloc

4、free

三、C++内存管理方式


一、C\C++内存分配

 C\C++内存分区示意图如下:

1、栈区

  • 栈区由编译器自动分配释放,由操作系统自动管理,无须手动管理。
  • 栈区上的内容只在函数范围内存在,当函数运行结束,这些内容也会自动被销毁。
  • 栈区按内存地址由高到低方向生长,其最大大小由编译时确定,速度快,但自由性差,最大空间不大。
  • 栈区是先进后出原则,即先进去的被堵在屋里的最里面,后进去的在门口,释放的时候门口的先出去。
  • 临时创建的局部变量const定义的局部变量存放在栈区
  • 函数调用和返回时,其入口参数返回值存放在栈区。

2、堆区

  • 堆区由程序员分配内存和释放。
  • 堆区按内存地址由低到高方向生长,其大小由系统内存/虚拟内存上限决定,速度较慢,但自由性大,可用空间大。
  • 通过malloc / calloc / relloc与free、new与delete完成堆区内存管理。

3、全局(静态)区

  • 通常是用于那些在编译期间就能确定存储大小的变量的存储区,但它用于的是在整个程序运行期间都可见的全局变量和静态变量。
  • 全局区有 .bss段 和 .data段组成,可读可写。
  • 未初始化的全局变量和未初始化的静态变量存放在.bss段。
  • 初始化为0的全局变量和初始化为0的静态变量存放在.bss段。
  • .bss段不占用可执行文件空间,其内容由操作系统初始化。
  • 已初始化的全局变量存放在.data段。
  • 已初始化的静态变量存放在.data段。
  • .data段占用可执行文件空间,其内容有程序初始化。

4、常量区

  • 字符串数字等常量存放在常量区。
  • const修饰的全局变量存放在常量区。
  • 程序运行期间,常量区的内容不可以被修改。

5、代码段

  • 程序执行代码存放在代码区,其值不能修改(若修改则会出现错误)。
  • 字符串常量和define定义的常量也有可能存放在代码区。

二、C语言内存管理方式

通过malloc / calloc / relloc与free进行内存管理,使用这几个函数需包含头文件<stdlib.h>。

1、malloc

 void* malloc (size_t size);

这个函数向内存申请⼀块连续可⽤的空间,并返回指向这块空间的指针。

  • 如果开辟成功,则返回⼀个指向开辟好空间的指针。
  • 如果开辟失败,则返回⼀个 返回值的类型是 NULL 指针,因此malloc的返回值⼀定要做检查。
  • void* ,所以malloc函数并不知道开辟空间的类型,具体在使⽤的时候使用者自己来决定。
  • 如果参数 size 为0,malloc的⾏为是标准是未定义的,取决于编译器。

2、calloc

void* calloc (size_t num, size_t size);
  • 函数的功能是为 num 个⼤⼩为 size 的元素开辟⼀块空间,并且把空间的每个字节初始化为0。
  • 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全 0。

3、relloc

有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时 候内存,我们⼀定会对内存的⼤⼩做灵活的调整。那realloc 函数就可以做到对动态开辟内存大小的调整。

void* realloc (void* ptr, size_t size);
  • ptr 是要调整的内存地址
  • size 调整之后新⼤⼩
  • 返回值为调整之后的内存起始位置。 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。

realloc在调整内存空间的是存在两种情况:

  1. 原有空间之后有足够大的空间,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
  2. 原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找⼀个合适⼤小的连续空间来使用。这样函数返回的是⼀个新的内存地址。

4、free

void free (void* ptr);

free函数⽤来释放动态开辟的内存。

  • 如果参数 ptr 指向的空间不是动态开辟的,那free函数的⾏为是未定义的。
  • 如果参数 ptr 是NULL指针,则函数什么事都不做。

void Test ()
{
    int* p1 = (int*) malloc(sizeof(int));
    free(p1);
    // 1.malloc/calloc/realloc的区别是什么?
    int* p2 = (int*)calloc(4, sizeof (int));
    int* p3 = (int*)realloc(p2, sizeof(int)*10);
    // 这里需要free(p2)吗?
    free(p3 );
}

三、C++内存管理方式

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因 此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

void Test()
{
    // 动态申请一个int类型的空间
    int* ptr4 = new int;
    // 动态申请一个int类型的空间并初始化为10
    int* ptr5 = new int(10);
    // 动态申请10个int类型的空间
    int* ptr6 = new int[3];
    delete ptr4;
    delete ptr5;
    delete[] ptr6;
}

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用 new[]和delete[],注意:匹配起来使用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值