动态内存管理

简介: 动态内存管理

💓博主csdn个人主页:小小unicorn💓

⏩专栏分类:c语言

🚚代码仓库:小小unicorn的学习足迹🚚

🌹🌹🌹关注我带你学习编程知识


1.为什么存在动态内存分配

先思考一下,按照我们现有的知识,内存开辟方式有两种

int val=20;
char arr[10]={0};

但是上面开辟空间的方式有两个特点

1.空间开辟大小是固定的

2.数组在声明的时候,必须指定数组的大小,它所需的内存在编译时分配

往往对内存分配不能局限,那么就可以试试动态内存分批

2.动态内存函数的介绍

2.1 malloc和free函数

c语言提供了一个动态内存开辟的函数

void*malloc(size_t size);

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

代码示例

#include<stdio.h>
#include<stdlib.h>
int main()
{
  int* p = (int*)malloc(40);
  if (p == NULL)
  {
    perror("malloc");
    return 1;
  }
  //开辟成功
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    printf("%d\n", *(p + i));
  }
  return 0;
}

运行结果如下:

让我们通过画图来简单分析一下:

在内存中,系统会划分为三个区域。分别为栈区,堆区以及静态区

在堆区里,我们实现动态内存开辟。值得注意的是:malloc申请到空间后,直接返回这块空间的起始地址,不会初始化空间的内容。

当malloc申请的内存空间,当程序退出时,还给操作系统,当程序不退出时,动态申请的内存,不会主动释放,因此我们需要使用free函数来进行释放

free函数原型如下:

void free(void*ptr);

示例:

用free 函数来释放内存要注意一点,free只能释放动态开辟的空间。

下面这个例子就是错误的,

2.1 calloc函数

函数原型

void*calloc(size_t num,size_t size)

calloc函数与malloc函数不一样的地方就是,calloc函数在开辟空间会进行初始化操作,会在返回地址之前把申请的空间的每个字节初始化为0

代码示例:

int main()
{
  int* p = (int*)calloc(INT_MAX, sizeof(int));
  if (p == NULL)
  {
    perror("calloc");
    return 1;
  }
  //打印数据
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    printf("%d", p[i]);
  }
  //释放
  free(p);
  p = NULL;
  return 0;
}

总结一下:如果我们对申请的内存空间的内容要求初始化的时候,那么我们可以很方便的使用calloc函数来完成任务

2.1 realloc函数

函数原型:

void*relloc(void*ptr,size_t siuze);

ptr是要调整的内存地址

size是调整之后新大小

返回值为调整之后的内存起始位置

代码示例:

int main()
{
  int* p = (int*)malloc(40);
  if (p == NULL)
  {
    perror("malloc");
    return 1;
  }
  //初始化为1-10
  int i = 0;
  for (i = 0; i < 10; i++)
  {
    p[i] = i + 1;
  }
  //增加一些空间
  int* ptr = (int*)realloc(p, 80);
  if (ptr != NULL)
  {
    p = ptr;
    ptr = NULL;
  }
  else
  {
    perror("realloc");
    return 1;
  }
  //打印数据
  for (i = 0; i < 20; i++)
  {
    printf("%d\n",p[i]);
  }
  //释放
  free(p);
  p = NULL;
  return 0;
}

运行结果:

这里呢,需要用画图来分析一下realloc是如何来开辟空间的

具体分两种情况:

情况1:

情况2:

3.总结

通过本篇文章,我们了解并学习了什么是动态内存,以及通过学习malloc,calloc和realloc函数来开辟内存,用free函数来释放内存。

补充一下

C/C++程序内存分配的几个区域:

  1. 栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结
    束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是
    分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返
    回地址等。
  2. 堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分
    配方式类似于链表。
  3. 数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。
  4. 代码段:存放函数体(类成员函数和全局函数)的二进制代码。

本篇文章到这就结束了,希望对大家有所帮助!

相关文章
|
12天前
|
程序员
动态内存管理
动态内存管理
10 0
|
12月前
|
C语言 Python
动态内存管理(下)
动态内存管理(下)
54 0
|
6月前
|
程序员 编译器 C语言
带你彻头彻尾了解『动态内存管理』
带你彻头彻尾了解『动态内存管理』
|
11月前
|
编译器
动态内存管理(1)
动态内存管理(1)
57 0
|
11月前
|
程序员 C语言 C++
动态内存管理-2
动态内存管理
40 0
|
11月前
|
程序员 编译器 C语言
动态内存管理总结
动态内存管理总结
53 0
|
12月前
|
编译器 文件存储 数据库
Day_17> 动态内存管理
Day_17> 动态内存管理
动态内存管理(下)
动态内存管理(下)
37 0
|
编译器 C++
动态内存管理详解
动态内存管理详解
119 0
|
编译器 C语言 C++
动态内存管理上
动态内存管理上