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所指的内存空间

相关推荐
后端小张2 分钟前
【JAVA 进阶】SpringMVC全面解析:从入门到实战的核心知识点梳理
java·开发语言·spring boot·spring·spring cloud·java-ee·springmvc
2301_789015623 分钟前
C++:二叉搜索树
c语言·开发语言·数据结构·c++·算法·排序算法
帅那个帅1 小时前
PHP里面的抽象类和接口类
开发语言·php
咖啡の猫7 小时前
Python字典推导式
开发语言·python
leiming67 小时前
C++ vector容器
开发语言·c++·算法
SystickInt8 小时前
C语言 strcpy和memcpy 异同/区别
c语言·开发语言
CS Beginner8 小时前
【C语言】windows下编译mingw版本的glew库
c语言·开发语言·windows
FJW0208148 小时前
Python_work4
开发语言·python
JAY_LIN——88 小时前
指针-数组
c语言·排序算法
大学生资源网9 小时前
java毕业设计之儿童福利院管理系统的设计与实现(源码+)
java·开发语言·spring boot·mysql·毕业设计·源码·课程设计