首页 > 编程语言 >C++(指针悬挂)

C++(指针悬挂)

时间:2024-07-29 23:40:15浏览次数:9  
标签:std 10 悬挂 int C++ ptr 指针

目录



指针悬挂(Dangling Pointer)是C++编程中常见的一个问题,它指的是一个指针指向了已经被释放或者无效的内存区域。当对悬挂指针进行解引用操作时,程序行为将是未定义的,可能会导致崩溃、数据损坏或其他意外行为。



1. 指针悬挂的成因

  1. 释放内存后继续使用指针
    当动态分配的内存被释放后,指针仍然指向原来的地址,这个地址现在是无效的。

    int* ptr = new int(10);
    delete ptr;
    *ptr = 20;  // 悬挂指针,未定义行为
    
  2. 局部变量的作用域结束
    当指针指向一个局部变量,而这个局部变量的作用域结束后,指针变成悬挂指针。

    int* ptr;
    {
        int localVar = 10;
        ptr = &localVar;
    }  // localVar 作用域结束
    *ptr = 20;  // 悬挂指针,未定义行为
    
  3. 对象被销毁后继续使用指针
    当指向对象成员的指针在对象被销毁后继续使用时,指针变成悬挂指针。

    class MyClass {
    public:
        int value;
    };
    MyClass* obj = new MyClass();
    int* ptr = &obj->value;
    delete obj;
    *ptr = 20;  // 悬挂指针,未定义行为
    


2. 防止指针悬挂的方法

  1. 释放内存后将指针置为空
    释放动态内存后,将指针设置为nullptr,以避免误用。

    int* ptr = new int(10);
    delete ptr;
    ptr = nullptr;  // 防止悬挂指针
    
  2. 智能指针
    使用智能指针(如std::unique_ptrstd::shared_ptr)来管理动态分配的内存,智能指针会自动处理内存释放问题。

    std::unique_ptr<int> ptr = std::make_unique<int>(10);
    // 无需手动删除内存,ptr超出作用域时自动释放
    
  3. 避免返回局部变量的地址
    不要返回局部变量的地址,确保指针指向有效的内存区域。

    int* getLocalVarAddress() {
        int localVar = 10;
        return &localVar;  // 错误,返回局部变量地址
    }
    
  4. 使用RAII(Resource Acquisition Is Initialization)
    利用RAII模式,在对象的生命周期内管理资源,确保资源在对象销毁时被正确释放。

    class ResourceGuard {
    public:
        ResourceGuard() { resource = new int(10); }
        ~ResourceGuard() { delete resource; }
    private:
        int* resource;
    };
    


3. 例子与实践

#include <iostream>

void safeUsage() {
    // 动态内存分配
    int* ptr = new int(10);
    std::cout << "Value: " << *ptr << std::endl;

    // 释放内存后,将指针置为空
    delete ptr;
    ptr = nullptr;

    if (ptr == nullptr) {
        std::cout << "Pointer is null" << std::endl;
    }
}

int main() {
    safeUsage();

    // 使用智能指针
    std::unique_ptr<int> smartPtr = std::make_unique<int>(20);
    std::cout << "Smart Pointer Value: " << *smartPtr << std::endl;

    return 0;
}


4. 总结

指针悬挂问题是C++中一个非常棘手的问题,需要开发者在编写代码时特别小心。通过良好的编程习惯和使用现代C++特性(如智能指针),可以大大降低出现悬挂指针的风险。确保每个指针始终指向有效的内存地址,并在不需要时及时释放资源,是防止指针悬挂的关键。



标签:std,10,悬挂,int,C++,ptr,指针
From: https://www.cnblogs.com/keye/p/18331305

相关文章

  • C++ 文件操作
    文件操作程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放通过文件操作可以将数据持久化C++中对文件操作需要包含头文件"fstream" 文件类型分为两种:文本文件:文件以文本的ASCII码的形式存储在计算机中二进制文件:文件以文本的二进制形式存储在计算机中,用户......
  • C语言:指针(1)
    一.内存和地址比如,我们的内存就相当⼀栋宿舍楼,楼里有很多的房间,每个房间都有一个房间号,每个房间里都住着8个人。这时如果你的朋友想要来找你,我们只需要把房间号告诉他就能快速的找到我们。然而,,在计算机中每个房间就相当一个内存单元,每个内存单元都有一个编号,每个编号对应着......
  • 2024年华为OD机试真题-找出作弊的人-(C++/Java/python)-OD统一考试(C卷D卷)
    2024华为OD机试真题目录-(B卷C卷D卷)-【C++JavaPython】  题目描述公司组织了一次考试,现在考试结果出来了,想看一下有没人存在作弊行为,但是员工太多了,需要先对员工进行一次过滤,再进一步确定是否存在作弊行为。过滤的规则为:找到分差最小的员工ID对(p1,p2)列表,......
  • 线程参数传递 同一个结构体指针,并且要传递id(0-xx)的方法
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、代码示例?总结前言提示:这里可以添加本文要记录的大概内容:线程参数传递同一个结构体指针,并且要传递id(0-xx)的方法在创建线程时候可能会遇到不仅要传递全局唯一的结构体指针给线程,还......
  • C++命名空间、标准输入输出、引用
    1、简述C++中命名空间的作用。答:避免重复定义全局变量的问题。2、定义两个命名空间A和B分别在A中和B中定义变量value。在main函数中将两个空间的value打印出来。#include"iostream"usingnamespacestd;namespaceA{intvalue=100;}namespaceB{intvalu......
  • c++修炼之路之二叉搜索树
    目录前言一:二叉搜索树的介绍 二:二叉搜索树的实现 1.查找2.insert(插入)3.erase(删除)4.析构函数5.拷贝构造 6.赋值重载7.插入,删除,查找的递归版本 三:二叉搜索树的应用四:二叉搜索树的性能接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧 前言对......
  • C语言------指针
    一、指针的理解与定义1.1变量的访问方式计算面中程序的运行都是在内存中进行的,变量也是内存中分配的空间,且不同类型的变量占用不同大小的空间。那如何问内存中变量存储的数据呢?有两种方式:直接访问和间接访问。直接访问:直接使用变量名进行的访问,以前的程序都是采用这种方式。......
  • C++提高编程—2、STL—基础知识以及Vector容器的数据插入和遍历
    2.1STL的诞生2.2STL的基本概念2.3STL的六大组件2.4STL中容器、算法、迭代器2.5容器算法迭代器初识2.5.1vector存放内置数据类型#include<iostream>usingnamespacestd;#include<vector>#include<algorithm>//标志算法头文件//vector容器存放内置......
  • 指针初步了解
    地址和指针概念        地址:在计算机内存中,每个存储单元都有一个唯一的地址,就像我们现实生活中的门牌号码一样。通过这个地址,我们可以找到相应的存储单元,从而访问其中存储的数据。        指针:指针则是一个特殊的变量,它存储的是内存地址。可以将指针想象成一......
  • C语言:指针的进阶
    指针的进阶一、字符指针(一)字符指针(二)常量字符串和字符数组二、指针数组和数组指针(一)指针数组int*p1[10](二)数组指针int(*p2)[10]三、函数指针(一)函数指针1、概念2、两段有趣的代码(1)(*(void(*)()0))();(2)void(*signal(int,void(*)(int)))(int);(二)函数指针数组......