野指针的写法¶
以下是可能导致野指针的程序写法:
1. 指针变量没有初始化¶
错误示例
int* ptr;
*ptr = 5;
正确用法
int* ptr = new int;
*ptr = 5;
// 做完操作后再delete ptr;
正确用法-智能指针
std::unique_ptr<int> ptr(new int);
*ptr = 5;
// 可以不用显式delete,智能指针在作用域结束时自动释放
2. 使用已释放的指针¶
错误示例
int* ptr = new int;
delete ptr;
*ptr = 5;
正确用法
int* ptr = new int;
delete ptr;
ptr = nullptr; // 把指针置为 nullptr 避免野指针
正确用法-智能指针
std::unique_ptr<int> ptr(new int);
ptr.reset(); // 通过调用 reset() 方法,将智能指针置空
3. 未正确分配内存¶
错误示例
int* ptr = new int[5];
ptr = new int[10];
delete[] ptr;
正确用法
int* ptr = new int[5];
delete[] ptr;
ptr = new int[10];
// 做完操作后再 delete[] ptr;
正确用法-智能指针
std::unique_ptr<int[]> ptr(new int[5]);
// 智能指针在作用域结束时自动释放它所指向的内存
4. 返回被释放的堆栈变量的指针¶
错误示例
int* get_pointer() {
int value = 5;
int* ptr = &value;
return ptr;
}
int* ptr = get_pointer();
*ptr = 10;
正确用法
int* get_pointer() {
int* ptr = new int;
*ptr = 5;
return ptr;
}
int* ptr = get_pointer();
// 做完操作后再 delete ptr;
正确用法-智能指针
std::unique_ptr<int> get_pointer() {
return std::make_unique<int>(5); //使用 std::make_unique 分配内存
}
std::unique_ptr<int> ptr = get_pointer();
5. 越界访问数组¶
错误示例
int* ptr = new int[5];
ptr[5] = 5;
正确用法
int* ptr = new int[5];
ptr[4] = 5; // 应该将下标限制在 0 到 4 之间
// 做完操作后再 delete[] ptr;
正确用法-智能指针
std::vector<int> vec(5);
vec[4] = 5;
// 在作用域结束时,vec会自动释放其内存
6. 当作整数使用指向对象的指针¶
错误示例
class MyClass {
public:
int value;
};
MyClass* ptr = new MyClass;
int value = *reinterpret_cast<int*>(ptr);
正确用法
class MyClass {
public:
int value;
};
MyClass* ptr = new MyClass;
int value = ptr->value; // 或者使用 reinterpret_cast<int*>(ptr) 来安全地转换指针类型
// 做完操作后再 delete ptr;
正确用法-智能指针
class MyClass {
public:
int value;
};
std::shared_ptr<MyClass> ptr = std::make_shared<MyClass>();
int value = ptr->value;
// 在作用域结束时,ptr会自动释放其内存