【C语言指针进阶讲解】第五章:指针与内存管理
第五章:指针与内存管理
5.1 动态内存分配
在C语言中,动态内存分配允许程序在运行时申请所需的内存空间,而不是在编译时决定。这对处理可变大小的数据结构如链表、树和动态数组特别有用。C语言提供了几个标准库函数来实现动态内存分配,它们分别是:malloc
、calloc
、realloc
和 free
。
复习malloc
, calloc
, realloc
, free
-
malloc
:- 用于分配指定大小的内存块,返回指向内存块开头的指针。
- 返回的内存块未被初始化。
int *p = (int*)malloc(10 * sizeof(int)); // 分配10个整型数据的内存空间 if (p == NULL) { // 处理内存分配失败 }
-
calloc
:- 用于分配指定数量相同大小的内存块,并初始化为0。
- 参数为元素数量和每个元素的大小。
int *p = (int*)calloc(10, sizeof(int)); // 分配并初始化10个整型数据的内存空间 if (p == NULL) { // 处理内存分配失败 }
-
realloc
:- 用于调整先前分配的内存块的大小。
- 若重新分配成功,返回新的地址;若失败,返回NULL且原来的内存块保持不变。
p = (int*)realloc(p, 20 * sizeof(int)); // 调整内存块大小以容纳20个整型数据 if (p == NULL) { // 处理内存重新分配失败 }
-
free
:- 用于释放先前分配的内存,使其能够被重新利用。
free(p); // 释放先前分配的内存 p = NULL; // 避免悬空指针
示例代码:动态分配和释放内存中的指针数组
下面的代码展示了如何动态分配和释放一个指针数组:
#include <stdio.h>
#include <stdlib.h>
int main() {
int **array;
int rows = 4, cols = 5;
// 动态分配指针数组
array = (int**)malloc(rows * sizeof(int*));
if (array == NULL) {
perror("Failed to allocate memory");
return -1;
}
// 为每个指针分配数组
for (int i = 0; i < rows; i++) {
array[i] = (int*)malloc(cols * sizeof(int));
if (array[i] == NULL) {
perror("Failed to allocate memory");
return -1;
}
}
// 初始化并打印数组
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
array[i][j] = i * cols + j;
printf("%d ", array[i][j]);
}
printf("\n");
}
// 释放内存
for (int i = 0; i < rows; i++) {
free(array[i]);
}
free(array);
return 0;
}
以上代码动态分配了一个4x5的二维数组,并在程序结束前正确释放所有分配的内存。
5.2 内存泄漏与调试工具
内存泄漏的概念与常见原因
内存泄漏是指程序未能正确释放先前分配的内存空间,导致这些内存空间在程序运行期间一直无法重新利用,最终可能导致内存耗尽。以下是一些常见原因:
- 忘记释放内存:如忘记调用
free
。 - 指针丢失:如指针被重新赋值而未先
free
原来的内存。 - 局部指针失效:如在函数内分配的内存未被返回。
使用工具如valgrind
检测内存泄漏
Valgrind
是一个强大的内存调试工具,它可以检测内存泄漏、多重释放(double free)和非法访问等问题。使用方法如下:
-
安装
valgrind
(根据操作系统不同,安装命令可能不同)。对于Debian/Ubuntu系统:
sudo apt-get install valgrind
-
通过
valgrind
执行程序:valgrind --leak-check=full ./your_program
示例输出:
==12345== HEAP SUMMARY: ==12345== in use at exit: 72 bytes in 3 blocks ==12345== total heap usage: 9 allocs, 6 frees, 7,256 bytes allocated ==12345== ==12345== 72 bytes in 3 blocks are definitely lost in loss record 2 of 2 ==12345== at 0x4C2BBAF: malloc (vg_replace_malloc.c:299) ==12345== by 0x400556: main (main.c:7) ==12345== ==12345== LEAK SUMMARY: ==12345== definitely lost: 72 bytes in 3 blocks ==12345== indirectly lost: 0 bytes in 0 blocks ==12345== possibly lost: 0 bytes in 0 blocks ==12345== still reachable: 0 bytes in 0 blocks ==12345== suppressed: 0 bytes in 0 blocks ==12345== ==12345== For counts of detected and suppressed errors, rerun with: -v ==12345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
以上示例输出显示了72字节的内存泄漏,以及哪个代码位置导致了这一泄漏。通过这样的输出,程序员可以快速定位并修复内存泄漏问题。
通过本章的学习,读者应该能够理解并掌握如何在C语言中正确进行动态内存分配和释放,如何识别和修复内存泄漏问题,这对于编写高效、可靠的C程序非常重要。
原文地址:https://blog.csdn.net/fjw12998/article/details/142678851
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!