动态内存申请

1.6k 词

概念

动态内存申请实际上是在堆区开辟内存空间,而堆区空间手动开辟,手动释放,不像栈区由操作系统自动维护。同时,很多时候我们需要的内存空间取决于实际输入的数据,所以我们就需要动态分配内存了。

动态分配函数

  • 注意
    动态内存分配函数的使用需要注意以下几点:
    • 一般用memset初始化
    • 调用函数后一定要判断一下是否申请成功
    • 每次调用函数申请的空间是连续的,但是多次调用函数申请的空间不一定连续。
    • 返回的是void *指针,在调用函数时,需要强制类型转换成我们需要的类型。即-养成调用函数前面接强转的好习惯。
    • 内存空间使用完之后一定要释放
      ,否则会造成内存泄漏

malloc函数

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdlib.h>
void *malloc(size_t size)
/*
功能:
在堆区开辟指定长度的连续内存空间
参数:
size指定开辟内存空间的大小,单位为字节
size的类型size_t本质是unsigned int的typdef
返回值:
返回指向开辟内存空间首地址的指针(void *),
如果开辟失败,返回NULL
*/
  • 堆区中分配一块长度为size字节的连续存储空间;并返回指向该存储空间首地址的指针,分配失败时,返回NULL。

calloc函数

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdlib.h>
void *calloc(unsigned int n, size_t size)
/*
功能:
在堆区开辟指定长度的连续内存空间,并初始化为0
参数:
n指定开辟内存空间的个数
size指定开辟内存空间的大小,单位为字节
size的类型size_t本质是unsigned int的typdef
返回值:
返回指向开辟内存空间首地址的指针(void *),
如果开辟失败,返回NULL
*/
  • 在堆区中分配一块长度为n×size字节的连续存储空间;并返回指向该存储空间首地址的指针;分配失败时,返回NULL。
  • malloc只分布内存不负责初始化不同,calloc分配的空间被初始化为0

realloc函数

调用malloccalloc函数单次申请的内存是连续的,两次申请的两块内存不一定连续。为了满足这种需求,即我先用malloc或者calloc申请了一块内存,我还想在原先内存的基础上挨着申请内存。或者我开始时候使用malloccalloc申请了一块内存,我想释放后边的一部分未使用的内存。为了解决这个问题,发明了realloc这个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdlib.h>
void *realloc(void *ptr, size_t newsize)
/*
功能:
重新分配内存空间,调整已分配内存空间的大小
参数:
ptr指向要重新分配内存空间的指针
newsize指定重新分配内存空间的大小,单位为字节
newsize的类型size_t本质是unsigned int的typdef
返回值:
返回指向重新分配内存空间首地址的指针(void *),
如果分配失败,返回NULL
*/
  • 如果传入的指针的内存空间
    后面有足够的空间,则直接调整大小,并返回指针;
  • 如果传入的指针的内存空间后面没有足够的空间,则重新开辟一块大小为newsize字节的内存空间,并将原内存空间的内容复制到新内存空间中,并返回新内存空间的指针;
  • 如果传入的指针为NULL,则相当于调用malloc函数;
  • 如果newsize小于传入的指针指向的内存空间,则只调整大小,不改变内容。

free函数

1
2
3
4
5
6
7
8

#include <stdlib.h>
void free(void *ptr)
/*
功能:释放堆区空间
参数:ptr指向要释放的内存空间
返回值:无
*/
  • 释放指针指向的内存空间
  • ptr必须是malloccallocrealloc函数返回的指针,否则结果是未定义的。