C语言文章更新目录
C语言学习资源汇总,史上最全面总结,没有之一
C/C++学习资源(百度云盘链接)
计算机二级资料(过级专用)
C语言学习路线(从入门到实战)
编写C语言程序的7个步骤和编程机制
C语言基础-第一个C程序
C语言基础-简单程序分析
VS2019编写简单的C程序示例
简单示例,VS2019调试C语言程序
C语言基础-基本算法
C语言基础-数据类型
C语言中的输入输出函数
C语言流程控制语句
C语言数组——一维数组
C语言数组——二维数组
C语言数组——字符数组
C语言中常用的6个字符串处理函数
精心收集了60个C语言项目源码,分享给大家
C语言核心技术——函数
C代码是怎样跑起来的?
C语言实现字符串的加密和解密
C语言——文件的基本操作
使用C语言链表创建学生信息并且将信息打印输出
图解C语言冒泡排序算法,含代码分析
实例分析C语言中strlen和sizeof的区别
开发C语言的3款神器,VS2019、VScode和IntelliJ Clion
动图图解C语言选择排序算法,含代码分析
动图图解C语言插入排序算法,含代码分析
C语言指针数组和数组指针详解
5分钟搞懂C语言中的传值和传址
C语言——动态数组的创建和使用
C语言中#include<…>和#include“…“的区别
2024年C语言最新经典面试题汇总(1-10)
2024年C语言最新经典面试题汇总(11-20)
C语言实例专栏(持续更新中…)
C语言中允许程序在运行时创建和释放内存,以适应程序数据结构的大小变化或其他不确定的内存需求。也就是常说的动态内存分配。
这篇文章将详细介绍动态分配内存并进行操作的基本步骤以及注意事项。
动态内存分配的函数
1. malloc()
用于分配指定大小的内存块。其函数原型如下:
void *malloc(size_t size);
malloc()
接受一个参数 size
,表示需要分配的字节数。如果内存分配成功,它返回一个指向已分配内存区域的指针;否则,若无法分配足够的内存,返回 NULL
。
2. calloc()
与 malloc()
类似,但额外提供了分配内存并将其所有字节初始化为零的功能。其函数原型如下:
void *calloc(size_t num, size_t size);
calloc()
接收两个参数:num
表示元素数量,size
表示每个元素的大小。它为 num
个大小为 size
的元素分配内存,并清零。返回值与 malloc()
相同。
3. realloc()
用于调整已分配内存块的大小。其函数原型如下:
void *realloc(void *ptr, size_t size);
realloc()
接收两个参数:ptr
是先前通过 malloc()
、calloc()
或 realloc()
分配的内存区域的指针,size
是新的所需大小。它尝试调整指定内存块的大小,如果必要,可能会移动内存块到另一个位置。返回值为调整后内存块的新地址(可能与原地址相同或不同),若分配失败,则返回 NULL
,此时原始内存块保持不变。
4. free()
用于释放之前动态分配的内存。其函数原型如下:
void free(void *ptr);
free()
接收一个参数 ptr
,即之前由内存分配函数返回并不再使用的内存区域的指针。调用 free()
后,该内存区域被释放,可供后续分配使用。
动态内存分配的操作步骤
分配内存:
// 分配一个整数数组,包含10个元素
int *dynamicArray = (int*)malloc(sizeof(int) * 10);
// 或者使用calloc,同时初始化为零
int *zeroInitializedArray = (int*)calloc(10, sizeof(int));
使用分配的内存:
// 填充动态数组
for (int i = 0; i < 10; ++i) {
dynamicArray[i] = i * i;
}
// 访问和操作动态分配的数据
printf("Element at index 5: %d\n", dynamicArray[5]);
调整内存大小(如果需要):
// 假设需要增加数组容量至20个元素
int *temp = (int*)realloc(dynamicArray, sizeof(int) * 20);
if (temp != NULL) {
dynamicArray = temp; // 更新指针
} else {
// 处理失败情况,可能保持原大小或采取其他策略
printf("Failed to reallocate memory.\n");
}
释放内存:
// 使用完毕后释放内存
free(dynamicArray);
dynamicArray = NULL; // 可选:将指针置为NULL,防止后续误用
动态内存分配函数的实例
1. malloc()
示例
#include <stdio.h>
#include <stdlib.h>
int main() {
// 分配一个能存储10个整数的空间
int *dynamicArray = (int*)malloc(sizeof(int) * 10);
if (dynamicArray == NULL) {
printf("Memory allocation failed.\n");
return 1;
}
// 使用分配的内存
for (int i = 0; i < 10; ++i) {
dynamicArray[i] = i * i;
}
// 输出动态数组的内容
for (int i = 0; i < 10; ++i) {
printf("Element at index %d: %d\n", i, dynamicArray[i]);
}
// 释放内存
free(dynamicArray);
dynamicArray = NULL;
return 0;
}
运行结果
在这个例子中,我们首先使用 malloc()
分配了一个能存储10个整数的空间。然后,我们填充这个动态数组,并打印其内容。最后,我们调用 free()
释放内存,并将指针置为 NULL
,防止后续误用。
2. calloc()
示例
#include <stdio.h>
#include <stdlib.h>
int main() {
// 分配并初始化一个能存储5个浮点数的空间
float *initializedArray = (float*)calloc(5, sizeof(float));
if (initializedArray == NULL) {
printf("Memory allocation failed.\n");
return 1;
}
// 使用分配的内存
for (int i = 0; i < 5; ++i) {
initializedArray[i] = 1.0f / (i + 1);
}
// 输出初始化后的动态数组
for (int i = 0; i < 5; ++i) {
printf("Element at index %d: %.2f\n", i, initializedArray[i]);
}
// 释放内存
free(initializedArray);
initializedArray = NULL;
return 0;
}
运行结果
此例中,我们使用 calloc()
分配并初始化了一个能存储5个浮点数的空间。所有元素初始值为0.0。然后,我们填充这个动态数组并打印其内容。最后,我们释放内存并将指针置为 NULL
。
3. realloc()
示例
#include <stdio.h>
#include <stdlib.h>
int main() {
int *dynamicArray = (int*)malloc(sizeof(int) * 5);
if (dynamicArray == NULL) {
printf("Memory allocation failed.\n");
return 1;
}
// 填充初始的动态数组
for (int i = 0; i < 5; ++i) {
dynamicArray[i] = i * i;
}
// 打印初始数组内容
printf("Initial array:\n");
for (int i = 0; i < 5; ++i) {
printf("Element at index %d: %d\n", i, dynamicArray[i]);
}
// 尝试将数组容量扩展至10个元素
int *temp = (int*)realloc(dynamicArray, sizeof(int) * 10);
if (temp != NULL) {
dynamicArray = temp;
// 填充新增的元素
for (int i = 5; i < 10; ++i) {
dynamicArray[i] = i * i;
}
} else {
printf("Failed to reallocate memory. Keeping original size.\n");
}
// 打印扩展后的数组内容(或保持原大小)
printf("Reallocated array:\n");
for (int i = 0; i < (temp == NULL ? 5 : 10); ++i) {
printf("Element at index %d: %d\n", i, dynamicArray[i]);
}
// 释放内存
free(dynamicArray);
dynamicArray = NULL;
return 0;
}
运行结果
在这个例子中,我们首先使用 malloc()
分配了一个能存储5个整数的空间,并填充了初始值。然后,我们尝试使用 realloc()
将数组容量扩展至10个元素。如果成功,我们填充新增的元素;否则,保持原大小。最后,我们打印扩展后的数组内容(或保持原大小),并释放内存。
注意事项
-
检查返回值:在使用
malloc()
、calloc()
和realloc()
后,应检查返回的指针是否为NULL
,以判断分配是否成功。 -
避免内存泄漏:当不再需要动态分配的内存时,务必调用
free()
进行释放。忘记释放会导致内存泄漏,长期运行的程序可能因此耗尽系统资源。 -
匹配类型:分配内存时确保计算的大小与要存储的数据类型相符。使用
sizeof
运算符可以确保正确计算所需字节数。 -
不要对未分配的内存或已释放的内存进行操作:这会导致未定义行为,严重时程序崩溃。
-
使用
realloc()
时保护原有数据:如果realloc()
返回新的地址,记得更新指向内存区域的所有指针,因为原有的内存可能已被移动。同时,如果realloc()
失败,原内存块保持不变,仍可继续使用。 -
避免内存碎片:合理规划内存分配与释放,减少频繁的小块内存分配与释放,有助于降低内存碎片,提高内存利用率。
-
遵循分配与释放对称原则:确保每个
malloc()
、calloc()
或realloc()
都有对应的free()
调用,且释放的是同一指针。