在C语言中,动态内存分配是通过标准库中的几个关键函数来实现的,这些函数包括malloc
、calloc
、realloc
和free
。动态内存分配允许程序在运行时根据需要分配和释放内存,这对于处理大小不确定的数据结构(如链表、树等)尤为重要。下面将详细介绍这些函数的使用方法,并给出示例代码。
动态内存分配函数
-
「
malloc
」- 「功能」:在堆上分配指定大小的内存块,并返回指向该内存块的指针。
- 「原型」:
void*malloc(size_t size);
- 「参数」:
size
为需要分配的内存字节数。 - 「返回值」:成功时返回指向分配内存的指针;失败时返回
NULL
。 - 「注意事项」:分配的内存未初始化,使用前需手动初始化。
-
「
calloc
」- 「功能」:在堆上分配指定数量和大小的连续内存块,并将每个字节初始化为0。
- 「原型」:
void*calloc(size_t num, size_t size);
- 「参数」:
num
为需要分配的元素数量,size
为每个元素的大小。 - 「返回值」:成功时返回指向分配内存的指针;失败时返回
NULL
。 - 「注意事项」:分配的内存已初始化为0,适合用于需要初始化的场景。
-
「
realloc
」- 「功能」:调整已分配内存块的大小,可以增加或减少内存大小。
- 「原型」:
void*realloc(void *ptr, size_t size);
- 「参数」:
ptr
为指向已分配内存块的指针,size
为新的内存大小。 - 「返回值」:成功时返回指向调整后内存块的指针;失败时返回
NULL
,原内存块不变。 - 「注意事项」:如果新的内存大小为0,则相当于调用
free(ptr)
;如果分配失败,原内存块不会被释放,需手动处理。
-
「
free
」- 「功能」:释放之前通过
malloc
、calloc
或realloc
分配的内存块。 - 「原型」:
void free(void*ptr);
- 「参数」:
ptr
为指向已分配内存块的指针。 - 「返回值」:无返回值。
- 「注意事项」:释放后指针应置为
NULL
,避免悬空指针。
- 「功能」:释放之前通过
示例代码
示例1:动态分配数组
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
printf("请输入数组的大小: ");
scanf("%d", &n);
// 动态分配内存
int *array = (int*)malloc(n * sizeof(int));
if (array == NULL) {
printf("内存分配失败\n");
return EXIT_FAILURE;
}
// 初始化数组
for (int i = 0; i < n; i++) {
array[i] = i + 1;
}
// 打印数组
printf("数组元素: ");
for (int i = 0; i < n; i++) {
printf("%d ", array[i]);
}
printf("\n");
// 释放内存
free(array);
array = NULL; // 避免悬空指针
return EXIT_SUCCESS;
}
示例2:动态调整数组大小
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 5;
// 动态分配内存
int *array = (int*)malloc(n * sizeof(int));
if (array == NULL) {
printf("内存分配失败\n");
return EXIT_FAILURE;
}
// 初始化数组
for (int i = 0; i < n; i++) {
array[i] = i + 1;
}
// 打印数组
printf("原始数组元素: ");
for (int i = 0; i < n; i++) {
printf("%d ", array[i]);
}
printf("\n");
// 调整数组大小
int new_size = 10;
int *new_array = (int*)realloc(array, new_size * sizeof(int));
if (new_array == NULL) {
printf("内存调整失败\n");
free(array);
return EXIT_FAILURE;
}
array = new_array;
// 初始化新增元素
for (int i = n; i < new_size; i++) {
array[i] = i + 1;
}
// 打印调整后的数组
printf("调整后的数组元素: ");
for (int i = 0; i < new_size; i++) {
printf("%d ", array[i]);
}
printf("\n");
// 释放内存
free(array);
array = NULL; // 避免悬空指针
return EXIT_SUCCESS;
}
示例3:动态分配结构体
#include <stdio.h>
#include <stdlib.h>
// 定义结构体
struct Point {
int x;
int y;
};
void printPoint(struct Point *p) {
printf("Point: (%d, %d)\n", p->x, p->y);
}
int main() {
// 动态分配结构体
struct Point *p = (struct Point*)malloc(sizeof(struct Point));
if (p == NULL) {
printf("内存分配失败\n");
return EXIT_FAILURE;
}
// 初始化结构体
p->x = 10;
p->y = 20;
// 打印结构体
printPoint(p);
// 释放内存
free(p);
p = NULL; // 避免悬空指针
return EXIT_SUCCESS;
}
示例4:动态分配链表
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构体
typedef struct Node {
int data;
struct Node *next;
} Node;
// 创建新节点
Node *newNode(int value) {
Node *node = (Node*)malloc(sizeof(Node));
if (node == NULL) {
printf("内存分配失败\n");
exit(EXIT_FAILURE);
}
node->data = value;
node->next = NULL;
return node;
}
// 打印链表
void printList(Node *head) {
Node *current = head;
while (current != NULL) {
printf("%d -> ", current->data);
current = current->next;
}
printf("NULL\n");
}
// 释放链表
void freeList(Node *head) {
Node *current = head;
while (current != NULL) {
Node *next = current->next;
free(current);
current = next;
}
}
int main() {
// 创建链表
Node *head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3);
// 打印链表
printList(head);
// 释放链表
freeList(head);
return EXIT_SUCCESS;
}
总结
动态内存分配是C语言中处理复杂数据结构的重要工具。通过合理使用malloc
、calloc
、realloc
和free
函数,可以灵活地管理内存资源,避免静态内存分配带来的限制。在使用动态内存分配时,需要注意以下几点:
- 「检查分配结果」:每次调用
malloc
、calloc
和realloc
后,都要检查返回值是否为NULL
,以确保内存分配成功。 - 「初始化内存」:使用
calloc
可以方便地初始化内存为0,而malloc
分配的内存未初始化,使用前需手动初始化。 - 「释放内存」:使用完动态分配的内存后,应及时调用
free
释放,避免内存泄漏。 - 「避免悬空指针」:释放内存后,将指针置为
NULL
,避免后续操作导致未定义行为。
通过上述示例和注意事项,可以更好地理解和应用C语言中的动态内存分配技术。
标签:gt,int,NULL,内存,动态内存,printf,array,数据结构,分配 From: https://blog.csdn.net/wang15510689957/article/details/144628813