欢迎关注本公众号,专注面试题拆解
分享一套视频课程《C++百万并发服务器开发》,有需要的加我微信获取:fb964919126
面试题:野指针产生的原因 怎么规避?
答案:野指针是指指向不确定内存地址的指针,通常会导致程序崩溃或不可预测的行为。(今天周末,来一道比较简单的题目)
1
主要产生原因
第一种情况:未初始化的指针
void example() {
int* p; // 未初始化
*p = 10; // 危险:p可能指向任何地方
}
第二种情况:已经释放的指针
void example() {
int* p = new int(10);
delete p; // 释放内存
*p = 20; // 危险:p成为野指针
}
第三种情况:数组越界
int arr[5];
int *ptr = arr;
ptr[5] = 10; // 数组越界
第四种情况:函数返回局部变量的指针
int* getLocalPtr() {
int local = 10;
return &local; // 危险:返回局部变量地址
}
2
如何规避?
1.使用 C++11 引入的智能指针(如 std::unique_ptr、std::shared_ptr 和 std::weak_ptr),这些智能指针会自动管理内存,避免野指针问题。
class SmartPointerSolution {
// 1. unique_ptr:独占所有权
void uniquePtr() {
std::unique_ptr<int> p = std::make_unique<int>(10);
// 自动释放,无需手动delete
}
// 2. shared_ptr:共享所有权
void sharedPtr() {
std::shared_ptr<int> p1 = std::make_shared<int>(10);
{
std::shared_ptr<int> p2 = p1; // 引用计数+1
} // p2离开作用域,引用计数-1
} // p1离开作用域,引用计数为0,释放内存
// 3. weak_ptr:弱引用,解决循环引用
void weakPtr() {
std::shared_ptr<int> sp = std::make_shared<int>(10);
std::weak_ptr<int> wp = sp;
if (auto p = wp.lock()) { // 安全地访问
std::cout << *p << std::endl;
}
}
};
2.RAII技术
// 资源获取即初始化
class RAIIExample {
private:
class ResourceGuard {
int* ptr;
public:
ResourceGuard() : ptr(new int(0)) {}
~ResourceGuard() { delete ptr; }
int* get() { return ptr; }
};
public:
void safe_usage() {
ResourceGuard guard; // 自动管理资源
int* p = guard.get();
// 使用p
} // 自动释放资源
};
3.避免返回局部变量的指针
不要返回局部变量的指针,可以返回局部变量的值或使用智能指针
std::unique_ptr<int> getPointer() {
auto ptr = std::make_unique<int>(10);
return ptr;
}
4.其他防御性编程
数组边界检查、
在关键位置使用范围检查和断言,确保指针的有效性、
使用静态分析工具(如 Clang-Tidy、Valgrind 等)检测潜在的野指针问题
总结:
没有总结,今天推荐一本书籍,如果是做后端开发的,非常值得一看。主要介绍系统软件的运行机制和原理,涉及在Windows和Linux两个系统平台上,一个应用程序在编译、链接和运行时刻所发生的各种事项,包括:代码指令是如何保存的,库文件如何与应用程序代码静态链接,应用程序如何被装载到内存中并开始运行,动态链接如何实现,C/C++运行库的工作原理,以及操作系统提供的系统服务是如何被调用的。
CppPlayer
关注,回复【电子书】珍藏CPP电子书资料赠送
精彩文章合集
专题推荐