如何检测或防止野指针
How to detect or prevent wild pointer
这段非常简单的代码演示了在复杂的环境中使用野指针会导致什么样的问题。
int main()
{
int *a1 = new int;
int *tmp = a1;
delete a1;
// Now, the tmp pointer is a wild pointer, it's dangerous.
int *a2 = new int;
delete tmp;
// Now, the a2 pointer may be a wild pointer.
}
有什么方法可以发现或防止这个问题吗?智能指针在这里有帮助吗?
使用智能指针。为什么不呢?
你的代码是无效的,会导致未定义的行为,但不管怎样- c++在内存使用方面不是很严格,这就是它的美丽(和诅咒…)。有一些外部工具可以帮助检测泄漏(尽管不是您所展示的那种情况),但归根结底还是要使用正确的结构和正确的编程。c++有很大的灵活性,但如果使用不当,就会出现严重的bug。
这个问题的解决方法很简单:
始终清楚代码中资源的所有权,并通过使用管理资源生命周期的类来强制这种所有权。
在这种情况下(假设您需要使用指针),我建议的生命周期如下:
//Limit the scope of the variables to the minimum required:
{
//a1 owns the pointer, so make it a `unique_ptr`
std::unique_ptr<int> a1(new int);
//tmp does not own the pointer, so make it a raw pointer
//limit its scope to a shorter scope than a1
int *tmp = a1.get();
}
//now the tmp pointer does not exist. It cannot be dangerous
//A similar strategy applies here
{
//a2 owns the pointer
std::unique_ptr<int> a2(new int);
}
//Again, a2 goes out of scope before any damage can occur.
您可以使用(至少在Linux上)像valgrind这样的工具来追踪这些bug。
你也可以使用Boehm的垃圾收集器(而不用担心释放内存)。
有些类(我认为设计得很糟糕)需要删除(即因为它们在析构函数中做重要的事情,除了释放内存)或者不应该有指向实例的手动指针。
阅读更多关于RAII的信息(RAII在c++中很常见,但不是通用的咒语:例如,好的Ocaml代码不遵循RAII)。
你可以使用智能指针
唯一的方法是尽可能多地对代码进行单元测试,使用valgrind等工具运行程序和单元测试,并希望捕获所有内存访问问题。
int *a2 = new int;
delete tmp;
//now, the a2 pointer may be a wild pointer
不,指针a2
指向一个有效的(非空闲的)位置。
据我所知,没有这样的方法来确定指针是否指向内存中的有效(非释放)位置。
对于您的第一个示例,您可以使用std::shared_ptr
对分配的内存位置的共享所有权进行建模。
有了C,没人能阻止你搬起石头砸自己的脚。
有很多方法可以让你的生活更轻松,比如c++智能指针:http://en.wikipedia.org/wiki/Smart_pointer#C.2B.2B_Smart_Pointers
诸如valgrind之类的工具将覆盖delete
语句,并将内存标记为无效,以便可以检测和报告后续访问。例如,常用的做法是在调试时用0xDEADBEEF
这样的值覆盖应该被删除的内存,这样您很快就知道正在访问已删除的内存区域。
对于生产,您通常希望跳过写入不再需要的内存,所以这些东西应该只在调试模式下启用。
- 在C++中释放内存期间,迭代器与指针有何不同
- SFINAE - 检测类型 T 是指针、数组还是带有随机访问运算符的容器,以及给定的值类型
- 对于循环不循环和检测字符数组 [指针和字符数组]
- 对于实际指针类型,用于检测类似指针(可取消引用)类型的模板函数失败
- 未检测到的空指针
- 未检测到越界指针算法?
- ***检测到的GLIBC *** MS2:free():无效指针:0xB7526FF4 ***
- 指向成员函数的指针与指向数据成员的指针有何不同
- gcc-如何检测基于指针的内存访问
- 对齐方式与指针中尾随零的数量有何关系
- glibc 检测到 *** free() 无效指针
- "空指针已通过",用于检测轮廓
- *** glibc检测到*** free():无效的指针:
- 为引用计数的智能指针检测内存泄漏的设计模式
- c++提升线程glibc检测到无效指针
- C++03 12.4/12对通过指针显式调用基类析构函数有何说明
- 检测到指针引用可能存在内存泄漏
- 检测"内存泄漏"时,瓦尔格林德的真实指针是什么?
- 一个弱/共享指针,检测是否还有一个用户,boost
- Lambda函数引用指针破坏检测