# 什么是内存泄漏?什么是野指针?什么是内存越界?如何避免?
# 简要回答
内存泄漏 是指程序申请了一块内存但忘记释放,就像借了钱却没还,时间一长占用越来越多资源。
野指针 是指一个指针指向了一块已经失效的内存,比如你用一把废掉的钥匙去开门,可能会引起程序崩溃。
内存越界 是访问了数组或内存的非法位置,相当于你住 101 室,却跑去 110 室开门,结果不是你家,还可能触发异常。
这三类问题都很危险,处理不好会导致程序崩溃、卡顿甚至系统漏洞。
- 如何避免
内存泄漏,手动释放,如果是C++可以使用智能指针。
野指针,可以进行初始化nullptr,释放后置为nullptr,避免返回局部变量的地址。
内存越界,严格检查数据的边界,使用std::vector,开启地址检查工具。
# 详细回答
- 内存泄漏
指程序在堆区上申请了内存但未释放,并且丢失了该内存的指针地址,造成这块内存无法再背访问或释放。
慢慢地,占内存越来越多,最终导致程序变慢甚至崩溃。
比如new后没有delete,malloc后没有free,指针还没释放就开始赋值,导致原来地址丢失。
- 野指针
指针本身还存在,但是它指向的内存已经被释放或者失效了。
再次访问可能会发生访问非法地址,造成崩溃、数据混乱。
比如delete了一个指针,却还在使用它。
- 内存越界
指对数组、指针或动态分配内存时,访问了未分配的内存区域,如数组越界,访问释放后的内存,字符串没有\0结尾,度超出了界。
- 怎么避免这些问题?
- 内存泄漏怎么避免?
手动释放,使用delete / free;使用智能指针 std::unique_ptr / std::shared_ptr。
- 野指针怎么避免?
所有指针先初始化为 nullptr,每次 delete 后,立刻把指针设为 nullptr,不要返回局部变量的地址。
- 内存越界怎么避免?
所有数组访问都要确认索引合法,使用 std::vector 等容器代替裸数组,编译时加上边界检查工具(如 -fsanitize=address)
# 代码示例
- 内存泄漏
//错误做法
void leak_example() {
int* p = new int[100]; // 申请了内存
// 忘记 delete[] p; 内存泄漏
}
//正确做法
void no_leak() {
int* p = new int[100];
// 用完一定要释放
delete[] p;
p = nullptr; // 清理后设空,避免野指针
}
2
3
4
5
6
7
8
9
10
11
12
- 野指针
//错误做法
void wild_pointer() {
int* p = new int(10);
delete p; // 内存释放了
*p = 20; // p 已经是野指针了,还在用
}
//正确做法
void safe_pointer() {
int* p = new int(10);
delete p;
p = nullptr; // 安全:空指针不能被使用
}
2
3
4
5
6
7
8
9
10
11
12
- 内存越界
//错误做法
void out_of_bounds() {
int arr[5] = {1, 2, 3, 4, 5};
arr[5] = 10; // 越界访问,合法索引是 0~4
}
//正确做法
void correct_access() {
int arr[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; ++i) {
arr[i] *= 2;
}
}
2
3
4
5
6
7
8
9
10
11
12
# 知识拓展
- 图解

- 一句话总结
内存的问题就三种:忘了还(泄漏),用了废的(野指针),越界胡来(越界);解决的办法说白了就两件事:记得还 + 别乱来。
- 面试官可能追问
- 智能指针真的能完全防止内存泄漏吗?
答:大多数情况下能防止,但需要注意 循环引用(shared_ptr 互相引用);解决方法是用 weak_ptr 打断引用环。
- 释放指针后为什么要设成 nullptr?
答:防止后续误用已经释放的地址;如果你不设为 nullptr,下次 if (p) 判断还会误以为可以用。
- 你说内存泄漏会导致程序崩溃,怎么崩?
答: 泄漏短期看可能不会崩,但会慢慢占满内存,系统调度、缓存压力增加;
长时间运行的服务、嵌入式设备特别敏感;
如果频繁分配小块内存但不释放,内存碎片严重,效率暴跌。
- free/delete 后为什么不能立即复用这块内存?
答:free/delete 只是告诉操作系统可以回收,并不一定马上清空内容,野指针仍然能访问这块内存(数据还在),这就是“悬空”。
评论
验证登录状态...