【C语言】动态内存管理

您所在的位置:网站首页 C语言作用域常见问题 【C语言】动态内存管理

【C语言】动态内存管理

2022-12-25 01:15| 来源: 网络整理| 查看: 265

目录

1. 为什么存在动态内存分配

2. 动态内存函数的介绍

2.1 malloc和free

2.2 calloc

2.3 realloc

3. 常见的动态内存错误

3.1 对NULL指针的解引用操作

3.2 对动态开辟空间的越界访问

3.3 对非动态开辟内存使用free释放

3.4 使用free释放一块动态开辟内存的一部分

3.5 对同一块动态内存多次释放

3.6 动态开辟内存忘记释放(内存泄漏)

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

5. 柔性数组

5.1 柔性数组的特点:

5.2 柔性数组的使用

1. 为什么存在动态内存分配

内存开辟方式有:

int val = 20;//在栈空间上开辟四个字节 char arr[10] = {0};//在栈空间上开辟10个字节的连续空间

但是上述的开辟空间的方式有两个特点:

1. 空间开辟大小是固定的。

2. 数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。

但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道, 那数组的编译时开辟空间的方式就不能满足了。 这时候就只能试试动态存开辟了。

2. 动态内存函数的介绍 2.1 malloc和free

C语言提供了一个动态内存开辟的函数:

void* malloc (size_t size);

参数size是要开辟的内存的大小(以字节为单位),返回值是指向这块空间的指针。

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

C语言提供了另外一个函数free,专门是用来做动态内存的释放和回收的,函数原型如下:

void free (void* ptr); 如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。如果参数 ptr 是NULL指针,则函数什么事都不做。如果程序不结束,动态内存不经过free释放,动态内存是不会被释放的。

malloc和free都声明在 stdlib.h 头文件中

例子:

#include #include #include int main() { //int arr[10];//向内存申请了40个字节 int* p = (int*)malloc(10*sizeof(int)); int* ptr = p; if (p == NULL) { printf("%s\n", strerror(errno));//输出错误信息 return 1; } int i = 0; for (i = 0; i < 10; i++) { *ptr = i; ptr++; } free(p); p = NULL; ptr = NULL; return 0; } 2.2 calloc void* calloc (size_t num, size_t size);

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

例子:

#include #include int main() { int *p = (int*)calloc(10, sizeof(int)); if(NULL != p) { int i = 0; for(i=0; ia[i] = i; //数组使用 } for (i = 0; i < 10; i++) { printf("%d ",ps->a[i]); //数组打印 } //若觉得40不够用,可用realloc扩容 //如: struct S* ptr = (struct S*)realloc(ps, sizeof(struct S) + 80); if (ptr == NULL) //检查是否为空指针 { perror("realloc"); return 1; } else { ps = ptr; } free(ps); //释放内存并置为空指针 ps = NULL; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3