指针用不好,内存就悄悄溜走了

写 C 或 C++ 时,你有没有遇到过程序跑着跑着就变慢、卡顿,甚至直接崩溃?有时候重启一下好了,过会儿又来——这很可能不是电脑问题,而是内存泄漏在作怪。

内存泄漏是啥?

简单说,就是你向系统申请了一块内存(比如用 mallocnew),用完后没还回去。系统以为你还要用,一直留着;可你的代码早就不碰它了。久而久之,可用内存越来越少,程序越来越“虚胖”。

指针,既是工具,也是隐患

指针本身不泄漏内存,但它常被用来管理动态分配的内存。问题出在:指针丢了、重用了、没释放,或者释放了还继续用。

比如这段常见错误:

int* ptr = (int*)malloc(sizeof(int) * 100);
ptr = (int*)malloc(sizeof(int) * 200); // 前一次 malloc 的 100 个 int 彻底找不到了

第一行申请的内存地址,被第二行直接覆盖掉了。没有变量再指向它,也没调用 free,这块内存就永远“失联”了。

怎么让指针帮我们防泄漏?

关键不是不用指针,而是养成“谁申请、谁释放”+“释放即置空”的习惯。

改写上面的例子:

int* ptr = (int*)malloc(sizeof(int) * 100);
// ... 使用 ptr
free(ptr);
ptr = NULL; // 释放后立刻设为 NULL

// 后面即使误用 if (ptr != NULL) { ... } 也能拦住
// 即使不小心再 free(NULL),C 标准也规定它是安全的

再比如函数返回动态内存时,别只顾着传指针,得明确责任归属:

char* load_config() {
char* buf = (char*)malloc(1024);
// 读取配置到 buf
return buf; // 调用者必须记得 free!
}

// 正确用法:
char* cfg = load_config();
if (cfg) {
printf("%s\n", cfg);
free(cfg);
cfg = NULL;
}

小技巧:用局部作用域约束指针生命周期

尽量把指针声明在最小需要的作用域里,用完立刻释放。别一股脑全堆在函数开头:

void process_image() {
// ❌ 不推荐:一大片 malloc 集中在开头,容易漏 free
int* data = malloc(...);
char* temp = malloc(...);
float* result = malloc(...);
// ... 中间几十行代码
// 忘了 free(temp)?
}

void process_image_v2() {
// ✅ 推荐:按需申请,用完即放
int* data = malloc(...);
// 处理 data
free(data); data = NULL;

char* temp = malloc(...);
// 处理 temp
free(temp); temp = NULL;
}

不是所有指针都要手动管——栈上变量(如 int x;)、全局变量、智能指针(C++11 后)都不用操心。但只要你写了 malloccallocreallocnew,就得亲手送它“落叶归根”。