【C】动态内存函数——大全(基本,简洁,包教会,适合初学)

简介: 【C】动态内存函数——大全(基本,简洁,包教会,适合初学)

一.动态内存函数介绍

内存函数的头文件:

include<stdlib.h>

1.free

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

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

使用场景:

int num=10;
int* p=NULL;
free(p);
p=NULL;

2.malloc

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

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

情景1:申请内存空间失败——返回空指针

情景2:动态内存的底层原理

  1. 局部变量特点,进函数时创建,出函数时销毁
  2. 局部变量放在栈区
  3. 动态内存分配放在堆区不会自动摧毁,直到程序退出才释放。(易造成爆内存

   


情景3:释放动态内存空间后还要把p置为空指针——防止野指针

释放动态内存空间后,p还会记得一个地址(野指针)

1. free(p);
2. p=NULL;

3.calloc

  • 函数的功能是为num个大小为size的元素开辟一块空间,并把空间每个字节都初始化为0
  • 与malloc的区别只在于calloc会在返回地址之前把申请的空间每个字节全初始化为0

      相当于calloc=malloc+memset

情景1:calloc开辟的值是0,而malloc开辟的空间没有初始化是随机值


4.realloc

  • ptr是要调整的内存地址
  • size是要调整后的新大小
  • 返回值为调整之后的内存起始位置
  • 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间 
  • 解决方案:使用时也要判断,创建临时指针ptr来判断,如果成功再给p指针

情景2:realloc调整空间,分类讨论(内存空间足够与否)

  1. 当内存空间足够时,拓展方法:就直接原有内存之后直接追加空间,原来空间数据不发生变化,这样函数返回的是原内存地址

情景1:realloc开辟失败,与malloc一样,返回的是NULL

  1. 当内存空间不足时,拓展方法:在堆空间上另外找一个合适的连续空间来使用,这样函数返回的是一个新的内存地址

情景4:realloc调整空间时,申请内存的起始位置是空指针 

申请内存起始位置是空指针时:等价于malloc

int*p=(int*)realloc(NULL,40);等价于malloc(40)


二.常见的动态内存错误

情景一:对空指针进行解引用

解决方法:判断指针是否为空

情景二:对动态开辟空间的越界访问

情景三:对非动态开辟的内存使用free释放 / 对同一块动态开辟的内存多次释放

解决方法:把p指针置为NULL,则无影响

情景四:使用free释放一块动态开辟内存的一部分

在释放时,p指针已经移动,指向的不再是动态内存空间的起始位置

解决方法:

  • 创建一个新指针ptr拷贝起始地址,遍历/移动指针时时用新指针ptr
  • 不改变"p指向的是动态内存空间的起始地址"的写法

     

情景五:未对动态开辟内存使用free释放——造成内存泄漏

指针会变成野指针,造成非法访问

三.几个经典的笔试题

例题1:

例题2:

例题3:内存泄漏

例题4:非法访问(野指针)

四.C/C++程序的内存开辟

五.柔性数组

C99中,结构中的最后一个元素允许是未知大小的数组

柔性数组的两种写法:

有些编译器无法编译时,可以改成:

1.柔性数组的特点

  • 结构中的柔性数组成员前面必须至少有一个其他成员

 

  • sizeof返回这种结构大小,不包括柔性数组的内存

     

  • 包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小

     

  • 柔性数组的体现——可以更改数组的大小
  •      

2.用另一种方式实现柔性数组功能

法二:“单独malloc块空间,在此之上realloc”

两种方式的对比:

  • 第一种方式好处:方便内存释放
  • 第二种方式好处:有利于访问速度(连续的内存有益于提高访问速度)
  • 第二种方式坏处:要进行两次释放,容易造成内存泄漏
相关文章
|
2月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
37 3
|
14天前
|
存储 缓存 算法
【C语言】内存管理函数详细讲解
在C语言编程中,内存管理是至关重要的。动态内存分配函数允许程序在运行时请求和释放内存,这对于处理不确定大小的数据结构至关重要。以下是C语言内存管理函数的详细讲解,包括每个函数的功能、标准格式、示例代码、代码解释及其输出。
45 6
|
2月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
3月前
|
存储 弹性计算 测试技术
阿里云服务器实例规格vCPU、内存、网络带宽、网络收发包PPS、连接数等性能指标详解
阿里云服务器ECS实例可以分为多种实例规格族。根据CPU、内存等配置,一种实例规格族又分为多种实例规格。而实例规格又包含vCPU、处理器、内存、vTPM、本地存储、网络带宽、网络收发包PPS、连接数、弹性网卡、云盘带宽、云盘IOPS等指标,本文为大家详细介绍实例规格的这些指标,以供大家了解和选择。
171 14
阿里云服务器实例规格vCPU、内存、网络带宽、网络收发包PPS、连接数等性能指标详解
|
2月前
|
存储 程序员 编译器
C语言——动态内存管理与内存操作函数
C语言——动态内存管理与内存操作函数
|
2月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
304 1
|
2月前
|
程序员 C语言
C语言内存函数精讲
C语言内存函数精讲
|
2月前
|
存储 编译器 C++
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作(二)
【C++】掌握C++类的六个默认成员函数:实现高效内存管理与对象操作
|
2月前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
34 0
|
2月前
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
43 0