目录
为什么要进行动态内存分配
在之前的学习中,我们开辟内存空间都是固定的,例如
int a = 0;//开辟4个字节的内存空间
int char[10] = { 0 };//开辟10个字节的连续内存空间
但是,如果遇到不知道或者不确定要但是内存空间的时候,这样显然就不合适了。所以就出现了动态内存
1.malloc和free
void* malloc(size_t size);
malloc申请的空间在内存的堆区

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
如果开辟成功,则返回一个指向开辟好空间的指针。
如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。
返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。
如果参数 size 为0,这个malloc的行为是C语言标准未定义的,取决于编译器。
C语言提供了另外一个函数free,专门是用来做动态内存的释放和回收的,函数原型如下:
void free (void* ptr);
free函数用来释放动态开辟的内存:
如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
如果参数 ptr 是NULL指针,则函数什么事都不做。
动态内存函数都包含于<stdlib.h>这个头文件中。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* ptr = (int*)malloc(40);//malloc 函数会返回所申请的内存块的起始地址,返回类型为void*
//将其强制类型转换为int*意思是所申请的这块空间之后将以整数对其进行访问操作
int* p = ptr;//因为malloc要返回申请空间的起始地址,所以通常不直接对ptr操作,而是另外创建
//一个指针存放ptr,后续对p进行操作
if (p == NULL)
{
//malloc函数在申请内存空间时,若空间大小不够,会返回一个空指针
//此时内存空间就会申请失败
perror("malloc:");//打印程序错误信息,双引号内的内容由自己定
//这里perror函数刚好可以验证空间是否申请成功
return 1;//主函数中return 1表示程序异常结束
}
int i = 0;
for (i = 0; i < 10; i++)//申请的空间大小为40个字节,转换为整形即10个整形
{
*p = i;
}
free(ptr);//申请的这块内存空间使用结束后,需要释放这片空间,free函数的参数为申请空间的起始地址
ptr = NULL;//空间释放后,ptr仍然指向空间内的一个有效地址,为避免后续对其使用造成野指针的情况
//通常在释放完空间后需将其置为空指针
//因此若后续需要对ptr进行操作,我们可以用一个if语句进行判断限制,即
//if (ptr != NULL)
//{
//*ptr = 100;
//}
//ptr被释放后若还对其使用,就会造成野指针
return 0;
}
当我们不释放动态申请的内存的时候
如果程序结束,动态申请的内存由操作系统自动回收
但是如果程序不结束,动态内存是不会自动回收的,就会形成内存泄漏的问题
内存泄漏就是说开辟的空间没被释放,这块空间就会一直存在并不被使用,
就像是这块空间突然消失了一样,所以称之为内存泄漏
需要说明的一点是:如果已经形成了内存泄漏,那么无论程序结束与否,那么这块空间都会被浪费掉,也就说内存泄漏一直存在。
2.calloc
void* calloc (size_t num, size_t size);
函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
C语言还提供了一个函数叫 calloc , calloc 函数也用来动态内存分配。原型如下:
void* calloc (size_t num, size_t size);
函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
3.常见的动态内存错误
(1)对NULL指针的解引用操作
(2)对动态开辟空间的越界访问
(3)对非动态开辟内存使用free释放
(4)使用free释放一块动态开辟内存的一部分
(5)对同一块动态内存多次释放
(6)动态开辟内存忘记释放(内存泄露)
4.柔性数组
结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组成员
特点
(1)结构中的柔性数组成员前面必须至少一个其他成员
(2)sizeof返回的这种结构大小不包括柔性数组的内存
(3)包含柔性数组成员的结构用malloc()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小
1766




被折叠的 条评论
为什么被折叠?



