C动态内存那些事

为什么存在动态内存分配?

首先,动态内存分配是计算机中一种重要的内存管理方法,它主要解决了静态内存分配无法灵活应对变化需求的问题。以下是几个存在动态内存分配的原因:

  1. 灵活性:动态内存分配允许程序在运行时根据需要动态地分配和释放内存。这对于需要动态改变内存使用情况的应用来说非常重要,比如动态数据结构、动态数组或者不确定大小的数据等。

  2. 节省内存:动态内存分配可以根据需求精确地分配所需大小的内存,避免了静态分配过多内存的浪费,并且可以回收不再使用的内存,提高内存的利用率。

  3. 动态数据结构支持:一些常见的数据结构,比如链表、树等,需要根据运行时的需求动态地分配内存来存储数据。动态内存分配可以满足这些数据结构的需要,使得程序能够更灵活地处理各种数据。

  4. 多任务支持:操作系统中的多任务环境下,每个任务需要独立的内存空间来存储自己的数据。动态内存分配允许每个任务根据需要独立分配内存,从而实现任务间的数据隔离,提高系统的安全性和可靠性。

其次值得注意的是,动态内存分配也需要注意管理好分配和释放内存的过程,避免内存泄漏或者其他内存管理问题。

动态内存管理函数

void* malloc(size_t size)

成功返回:开辟好空间的首地址,不会初始化空间内容,当程序退出时,还给操作系统,,当程序不退出,动态申请的内存,不会主动释放的

错误返回:NULL指针------NULL指针不可以使用,所以要对malloc返回的指针做检查

向内存申请一块连续可以的空间,并返回指向这块空间的指针

void* calloc(size_t num, size_t size);
  • num:要分配的元素个数。
  • size:每个元素的大小。
  • calloc函数会分配num * size字节的内存空间,并将所分配的内存块中的每个字节都初始化为0。这与使用malloc分配内存后手动初始化为0的效果相同。
void* realloc(void *ptr, size_t size);
  • ptr:指向之前分配的内存块的指针。(简单来说就是提前申请过的一块内存空间首地址)

  • size:要重新分配的内存块的大小。

  • realloc函数可以用来扩大或缩小已分配内存的大小。当ptr为NULL时,realloc的行为与malloc相同,即分配一块新的内存空间。当ptr不为NULL时,realloc会尝试重新分配ptr指向的内存块,将其大小调整为size所指定的大小。

  • (1)当新的大小size小于或等于原内存块的大小时,realloc会尝试缩小内存块的大小,并返回指向缩小后内存的指针。可能会丢失部分原有数据。

  • (2)当新的大小size大于原内存块的大小时,realloc会尝试扩大内存块的大小。如果扩大成功,会返回指向扩大后内存的指针。扩大后的新增内存区域的内容是未定义的。如果扩大失败,会保持原有内存块不变,并返回NULL。

  • (3)当ptr为NULL时,realloc会等同于malloc(size),即分配一块新的大小为size的内存块,并返回指向该内存块的指针。

由于这个函数很特别,下面通过一段代码结合画的内存图,方便大家理解

int main()

{

int* p=(int*)malloc(40);

if(p==NULL)

{

perror("malloc");

return 1;

}

int i=0;

for(i=0;i<10;i++)

{

p[i]=i+1;

}

p=realloc(p,80);

return 0;

}

下面是申请成功的情况,红色区域代码后边有占用的数据

第二种情况步骤

1.开辟新空间

2.将旧空间数据拷贝到新空间

3.释放旧空间

4.返回新空间起始地址

还有一种是内存申请失败的情况会造成内存泄漏

为了避免内存泄漏可以把

p=realloc(p,80);这段代码替换成

int* ptr=(int*)realloc(p,80);

if(ptr!=NULL)

{

p=ptr;

ptr=NULL;

}

else

{

perror("realloc");

return 1;

}

//释放

free(p);

void* free(void* ptr)

释放掉ptr所指的内存空间

相关推荐
不爱学习的小枫6 分钟前
scala的集合
开发语言·scala
梦醒沉醉7 分钟前
Scala的初步使用
开发语言·后端·scala
小白学大数据12 分钟前
Fuel 爬虫:Scala 中的图片数据采集与分析
开发语言·爬虫·scala
贩卖纯净水.26 分钟前
《React 属性与状态江湖:从验证到表单受控的实战探险》
开发语言·前端·javascript·react.js
JouJz31 分钟前
Java基础系列:深入解析反射机制与代理模式及避坑指南
java·开发语言·代理模式
白羊不吃白菜1 小时前
PAT乙级(1101 B是A的多少倍)C语言解析
c语言·开发语言
一号言安1 小时前
牛客python蓝桥杯11-32(自用)
开发语言·python
鸽鸽程序猿1 小时前
【JavaEE】SpringIoC与SpringDI
java·开发语言·java-ee
坚强小葵1 小时前
实验8-2-1 找最小的字符串
c语言·算法
@陽光總在風雨後1 小时前
调试正常 ≠ 运行正常:Keil5中MicroLIB的“量子态BUG”破解实录
c语言·arm开发·stm32·单片机·嵌入式硬件