推荐股票的好网站,网站开发 混合式 数据库,建设一个什么网站赚钱,phpcms 投资 网站源码目录
前言
一.malloc,free函数
1.malloc,free函数原型
2.使用方法
3.具体实例
4.注意事项
二.calloc函数
1.calloc函数原型
2.主要特点
3.使用案例
三.realloc函数
1.realloc函数原型
2.使用案例
3.注意事项 前言 动态内存是指在程序运行时#xff0c;按需分配和…目录
前言
一.malloc,free函数
1.malloc,free函数原型
2.使用方法
3.具体实例
4.注意事项
二.calloc函数
1.calloc函数原型
2.主要特点
3.使用案例
三.realloc函数
1.realloc函数原型
2.使用案例
3.注意事项 前言 动态内存是指在程序运行时按需分配和释放的内存空间。这种内存分配不在编译时固定而是在程序执行过程中根据实际需要分配并且可以手动释放。 以下介绍的函数都包含于头文件stdlib.h 为什么使用动态内存? 1.灵活性高。动态内存可以根据需要分配内存块。 2.避免浪费内存。动态内存允许程序根据需要分配精确的内存量从而更有效地使用内存资源。 一.malloc,free函数 malloc 是 C 标准库中用于动态内存分配的函数。它从堆heap中分配指定字节数的内存并返回指向这块内存的指针。如果内存分配失败它会返回 NULL。 free 函数是C标准库中的一个函数用于释放由动态内存分配函数如 malloc、calloc 或 realloc分配的内存。它的作用是将不再需要的动态内存归还给操作系统防止内存泄漏。 1.malloc,free函数原型 void* malloc(size_t size); size要分配的内存大小以字节为单位。返回值成功时返回指向已分配内存块的指针失败时返回 NULL。void*:返回值类型 void free(void* ptr); 参数 ptr一个指向要释放内存块的指针这个指针必须是通过 malloc、calloc 或 realloc 返回的指针。如果 ptr 为 NULLfree 不会执行任何操作。 返回值 free 没有返回值。 2.使用方法
(1)内存分配如
int* p (int*)malloc(sizeof(int)); // 为一个 int 类型变量分配内存(2)判断是否开辟空间成功(如果没有开辟成功直接使用指针可能回答导致程序崩溃未定义行为等),如:
if (p NULL) {perror(malloc);//打印错误信息的函数return 1;//分配失败退出程序
}
(3)释放内存(防止内存泄露),如:
free(p);
(4)将指针置为空(防止指针在释放内存地址后还指向原来那个地址相当于野指针,可能会导致未定义行为或者程序崩溃等等),如:
p NULL;
3.具体实例
#includestdio.h
#includestdlib.h
int main() {int* arr (int*)malloc(sizeof(int) * 10);//或者int* arr(int*)malloc(40);//判断是否分配内存成功if (arr NULL) {perror(malloc);//打印错误信息return 1;//分配失败,退出程序}//初始赋值for (int i 0; i 10; i) {arr[i] i 1;}//打印结果for (int i 0; i 10; i) {printf(%d , arr[i]);}//释放内存free(arr);//将arr置为空arr NULL;return 0;
}
需要注意的是:
在int* arr (int*)malloc(sizeof(int) * 10);这一语句中
1.(int*)是强制转换类型,将原本的返回值类型void*转化为我们需要定义的数据类型,当然这里我们定义的是int*类型的。
2.sizeof(int)*10是int类型的字节数乘以10,即我们要开辟4*1040个字节,开辟10个整型的空间,当然我们也可以这么写malloc(40),前提是你要计算好你需要开辟的字节数,否则在没有开辟够这么多的字节数的情况下越界访问数组可能会导致程序崩溃或者无限循环等的行为。
4.注意事项 malloc开辟的空间是没有创建初始值的。 举例如下:
#includestdio.h
#includestdlib.h
int main() {int* p (int*)malloc(sizeof(int) * 5);for (int i 0; i 5; i) {printf(%d , p[i]);}return 0;
}
结果是随机值: 二.calloc函数 calloc 是 C 语言中的标准库函数用于动态分配内存。与 malloc 类似calloc 也用于在堆上分配一块内存 1.calloc函数原型 void* calloc(size_t num, size_t size); num要分配的元素个数。size每个元素的大小以字节为单位。 2.主要特点
(1)分配并初始化内存为零 calloc 会分配一块内存并将这块内存中的所有字节初始化为 0。这与 malloc 的行为不同malloc 仅仅分配内存但不对内存进行初始化内存中的内容可能是垃圾值。 (2)两个参数 与 malloc 不同calloc 需要两个参数第一个参数是要分配的元素个数第二个参数是每个元素的大小。malloc 只需要一个参数总内存大小而 calloc 的目的是让用户更加清晰地定义数组类型的内存分配。 3.使用案例
#include stdio.h
#include stdlib.hint main() {int* arr (int*)calloc(5, sizeof(int)); // 分配5个int大小的空间且初始化为0if (arr NULL) {printf(Memory allocation failed!\n);return 1;}// 输出分配并初始化的数组for (int i 0; i 5; i) {printf(%d , arr[i]); // 输出结果将是 0 0 0 0 0}printf(\n);// 使用完成后释放内存free(arr);arrNULL; return 0;
}结果如图: 三.realloc函数 realloc 函数用于调整已经分配的动态内存的大小 1.realloc函数原型 void* realloc(void* ptr, size_t size); ptr指向已经通过 malloc, calloc 或者 realloc 分配的内存。如果 ptr 是 NULLrealloc 的行为与 malloc 类似分配一块新的内存。size新分配的内存大小以字节为单位。如果 size 为 0realloc 的行为与 free 类似会释放 ptr 指向的内存。 2.使用案例
(1)扩大内存
#include stdio.h
#include stdlib.hint main() {int* arr (int*)malloc(5 * sizeof(int)); // 分配5个int的内存if (arr NULL) {perror(malloc);return 1;}// 初始化数组for (int i 0; i 5; i) {arr[i] i;}//第一次打印for (int i 0; i 5; i) {printf(%d , arr[i]);}printf(\n);// 调整数组大小增加到10个intint* new_arr (int*)realloc(arr, 10 * sizeof(int));if (new_arr NULL) {perror(realloc);free(arr); // 如果失败释放原来的内存arr NULL;return 1;}// 如果重新分配成功继续使用新数组arr new_arr;// 初始化新增加的部分(第二次打印)for (int i 5; i 10; i) {arr[i] i;}// 输出数组for (int i 0; i 10; i) {printf(%d , arr[i]);}printf(\n);// 释放内存free(arr);arr NULL;return 0;
}结果如图: (2)缩小内存
#include stdio.h
#include stdlib.hint main() {// 分配 10 个 int 大小的内存int* arr (int*)malloc(10 * sizeof(int));if (arr NULL) {perror(malloc);return 1;}// 初始化数组for (int i 0; i 10; i) {arr[i] i 1;}printf(初始10个元素:\n);for (int i 0; i 10; i) {printf(%d , arr[i]);}printf(\n);// 使用 realloc 缩小数组到 5 个 intint* new_arr (int*)realloc(arr, 5 * sizeof(int));if (new_arr NULL) {perror(realloc);free(arr); // 如果 realloc 失败释放原来的内存arr NULL;return 1;}// 如果 realloc 成功继续使用缩小后的数组arr new_arr;printf(缩小后的元素:\n);for (int i 0; i 5; i) {printf(%d , arr[i]);}printf(\n);// 释放缩小后的内存free(arr);arr NULL;return 0;
}
结果如图: 注意事项
在缩小内存时数组后面的数据会丢失。程序只能访问缩小后剩余的那部分数据。 缩小内存后应确保访问的索引在新分配的范围内避免越界访问。
3.注意事项 扩展/缩小内存realloc 可以扩展或者缩小已经分配的内存块。如果扩展之前的数据会保留如果缩小超出部分会被释放。原内存的保留如果 realloc 需要移动内存块例如在当前内存空间不足的情况下它会自动分配新内存并将旧内存的数据复制过去原来的内存块会被释放。失败时不释放原内存如果 realloc 失败它不会释放原来的内存程序可以继续使用原来的 除了这三点我们还要注意一点我们来看一下代码:
就是用原来的指针接收申请的空间
#include stdio.h
#include stdlib.h
int main()
{int* ptr (int*)malloc(100);if (ptr ! NULL){//业务处理 }else{return 1;}//扩展容量 ptr (int*)realloc(ptr, 1000);//这样可以吗(如果申请失败会如何) free(ptr);return 0;
} 问题
如果 realloc 申请失败会返回 NULL。此时ptr 的原有地址即之前分配的内存将会被丢失导致 内存泄漏。由于 ptr 被覆盖成 NULL无法再释放之前申请的内存也无法继续使用。