悬垂指针(Dangling pointer)和野指针(Wild pointer)

参看维基百科:

Dangling pointer

迷途指针

===============================================================================================

温馨提示:由于本人英语水品有限,有些地方翻译得可能不准确,也比较生涩。

===============================================================================================

当所指向的对象被释放或者收回,但是对该指针没有作任何的修改,以至于该指针仍旧指向已经回收的内存地址,此情况下该指针便称悬垂指针(也叫迷途指针)。

某些编程语言允许未初始化的指针的存在,而这类指针即为野指针

悬垂指针的成因:

在许多编程语言中(比如C),显示地从内存中删除一个对象或者返回时通过销毁栈帧,并不会改变相关的指针的值。该指针仍旧指向内存中相同的位置,即使引用已经被删除,现在可能已经挪作他用。

一个简单的例子:

{
   char *dp = NULL;
   /* ... */
   {
       char c;
       dp = &c;
   } /* c falls out of scope */
     /* dp is now a dangling pointer */
}

如果操作系统能够侦测运行时的指向空指针的引用,一个方案是在内部快消失之前给dp赋为0(NULL)。另一个方案是保证dp在没有被初始化之前不再被使用。

另一个常见原因是混用 malloc() 和 free():当一个指针指向的内存被释放后就会变成悬垂指针。正如上个例子,可以避免这个问题的一种方法是在释放它的引用后把指针重置为NULL。

#include <stdlib.h>
 
void func()
{
    char *dp = malloc(A_CONST);
    /* ... */
    free(dp);         /* dp now becomes a dangling pointer */
    dp = NULL;        /* dp is no longer dangling */
    /* ... */
}

一个很常见的失误是返回一个栈分配的局部变量:一旦调用的函数返回了,分配给这些变量的空间被回收,此时它们拥有的是“垃圾值”。

int *func(void)
{
    int num = 1234;
    /* ... */
    return &num;
}

调用 func 后,尝试从该指针暂时能读取到正确的值(1234),但是再次调用函数后将会重写栈为 num 分配的的值,再从该指针读取的值就不正确了。如果必须要返回一个指向 num 的指针,num 的作用域必须大于这个函数——它也许被声明为 static。

野指针的成因:

野指针的产生是由于在首次使用之前没有进行必要的初始化。因此,严格地说,在编程语言中的所有为初始化的指针都是野指针。

int f(int i)
{
    char *dp;    /* dp is a wild pointer */
    static char *scp;  /* scp is not a wild pointer:
                        * static variables are initialized to 0
                        * at start and retain their values from
                        * the last call afterwards.
                        * Using this feature may be considered bad
                        * style if not commented */
}

 dp 是一个野指针。scp 不是一个野指针:静态变量一开始被初始化为0,从最后一次调用后保持着它们的值。如果没有注释,使用这个特性也许被视为不良风格。

避免悬垂指针错误:

在 C/C++ 中,一种最简单的技术是实现一个 free()(或类似的)替代版本或者 delete 析构器来保证指针的重置。然后,这个技术不会清除其他指针变量,它们含有该指针的副本。

/* Alternative version for 'free()' */
void safefree(void **pp)
{
    if (pp != NULL) {               /* safety check */
        free(*pp);                  /* deallocate chunk, note that free(NULL) is valid */
        *pp = NULL;                 /* reset original pointer */
    }
}
 
int f(int i)
{
    char *p = NULL, *p2;
    p = (char *)malloc(1000);    /* get a chunk */
    p2 = p;              /* copy the pointer */
    /* use the chunk here */
    safefree(&p);       /* safety freeing; does not affect p2 variable */
    safefree(&p);       /* this second call won't fail */
    char c = *p2;       /* p2 is still a dangling pointer, so this is undefined behavior. */
}

替换版本可以用来保证在调用 malloc() 之前一个空指针的正确性:

safefree(&p);        /* i'm not sure if chunk has been released */
p = malloc(1000);    /* allocate now */

这些用法可以通过 #define 指令来构造有用的宏指令,创建像元语言的东西来掩饰或者被嵌入到一个工具库中。但凡使用这个技术的程序员在会用到 free()的地方应该使用安全版本;不这么做会再次导致这些问题。另外,这个解决方案局限于单个程序或工程的作用域中,并且应该正确地写入文档。

在更多结构化的解决方案中,一种流行的避免悬垂指针的技术是使用智能指针。一个智能指针通常使用引用技术来收回对象。还有些技术包括 tombstones 方法和 locks-and-keys 方法。

另一个方法是使用 Boehm 垃圾收集器,一种保守的垃圾收集器,取代C和C++中的标准内存分配函数。此法通过禁止内存释放函数来完全消除悬垂指针引发的错误,通过收集垃圾来回收对象。

像Java语言,悬垂指针这样的错误是不会发生的,因为Java中没有明确地重新分配内存的机制。而且垃圾回收器只会在对象的引用数为0时重新分配内存。

转载于:https://www.cnblogs.com/submarinex/archive/2013/03/02/2940169.html

大白话说一说C++指针的非法访问 C++程序中的非法访问指针几乎可以说是C++编程中最致命的问题,也是现代C++之前较难排查的问题,随着现代C++(11/14/17/20)发布,基本可以依靠智能指针、STL容器、RAII规则、程序逻辑检查(Code Review)、单元测试、工具检测来避免非法访问指针的问题。Bjarne Stroustrup(C++ 之父)曾经说过:”资源管理是编写可靠软件的关键之一“,并将其视为当代 C++ 设计的核心原则。由于知识水平有限,难免会有错误或不严谨的地方,欢迎批评指正。 阅读详情

相关推荐

VS2015编译配置GDAL(图文并茂、超详细!!!)

文章目录一、GDAL介绍二、下载GDAL三、修改源代码四、工具命令提示符操作五、编译GDAL六、安装GDAL七、在VS2015的项目中配置GDAL八、添加环境变量九、测试是否配置成功 一、GDAL介绍 GDAL(Geospatial Data Abstraction Library)是一个在XMIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。它还有一系列命令行工具来进行数据转换处理。OGR是GDAL项目的一个分支,功能与GDAL类似,只不过它提供对矢量数据的支持。因此

weixin_46196863的博客 3734

悬垂指针指针

悬垂指针指针

m0_54711064的博客 1361

银行统一监管报送系统

依据《银行业金融机构数据治理指引》,银行业金融机构应当建立适应监管数据报送工作需要的信息系统,实现流程控制的程序化,提高监管数据加工的自动化程度。银行业金融机构应当将监管数据纳入数据治理,建立工作机制流程,确保监管数据报送工作有效组织开展,监管数据质量持续提升。银行通常要对接报送EAST5.0、1104、CRSS等近40个监管应用,涉及近1000张报表。表13-01是主要的监管报送应用、报送依据、报送规范、监管机构名称。

银行信息系统架构详解 4261

【基础知识】指针悬挂指针

指针是C/C++语言中一种特殊的数据类型,它的值是一块内存区域的地址。使用指针要求,它的值必须是指向一块分配给你使用的地址,且使用的内存不能超过它分配时的大小。例如: 这样的代码就给p分配一块有10个字节的内存,并把这块内存的开始地址放在p中。用户在使用时,必须保证引用的内存必须在以p开始到这块内存结束的范围内。 指针是指尚未初始化的指针,它指向的地址是未知的、不确定的、随机的。 释放内存后指针没有及时置空,依然指向该内存,有可能会出现非法访问的错误。简单的示例:

m0_56573171的博客 2490

Dangling pointer悬垂指针、迷途指针 Wild pointer指针

小邓笔记 6485

C语言中“指针”、“悬空指针”是什么?

“悬空指针指针”的套路深!

不脱发的程序猿 1万+

指针(Wild pointer)悬垂指针(dangling pointer)

详细参考如下: Dangling pointer悬垂指针、迷途指针 Wild pointer指针) 迷途指针经常出现在混杂使用malloc() free() 库调用: 当指针指向的内存释放了,这时该指针就是迷途的。前面的例子一样,一个避免这个错误的方法是在释放它的引用后将该指针的值重置为NULL 指针指的是还没有初始化的指针。严格地说,编程语言中每个指针在初始化前都是...

weixin_30878361的博客 437

C++指针与数组本质差异解析:从内存模型到性能优化实战

C++编程中,理解内存模型是掌握底层编程的关键。指针数组作为核心概念,虽然语法相似,但在内存布局、类型系统编译器行为上存在本质差异。指针本质是存储地址的变量,支持动态内存分配灵活算术运算,而数组是连续内存块的标识符,其大小在编译期确定。这种差异直接影响sizeof运算、函数参数传递内存管理策略。从技术价值看,深入理解指针与数组的关系有助于避免内存越界、悬垂指针等常见错误,并提升代码性能。在应用场景上,指针的动态性为构建链表、树等复杂数据结构提供了基础,而数组的确定性则在栈分配缓存友好性上具有优势

germmy-神一样的开发 660

C语言指针free后置NULL:3种常见错误场景与1个宏定义解决方案

本文深入探讨C语言指针free后置NULL的重要性,分析三种常见错误场景(双重释放、无效条件判断、悬垂引用),并提出使用SAFE_FREE宏的防御性编程解决方案。通过实战案例展示如何避免指针问题,提升代码健壮性可维护性,特别适合嵌入式开发内存敏感型项目。

weixin_30699955的博客 269

C++内存管理面试十大高频问题深度解析:从原理到实战避坑指南

内存管理是编程语言的核心基础,它决定了程序的性能、稳定性资源利用效率。其核心原理在于对计算机内存(堆、栈)的分配、使用释放进行有效控制,以避免内存泄漏、悬垂指针等问题。在C++这类系统级语言中,手动内存管理带来的技术价值是极致的性能控制与资源确定性,但同时也对开发者提出了更高要求。现代C++通过RAII(资源获取即初始化)原则、智能指针(如`std::unique_ptr`、`std::shared_ptr`)等机制,将资源生命周期与对象绑定,极大地提升了开发安全性与效率。这些技术的典型应用场景包括高性

weixin_34007020的博客 414

彻底搞清c/c++中的几个指针概念:悬垂指针智能指针以及哑指针指针

先看看下面两段代码运行结果: #include //#include using namespace std; int *p=NULL; void fun() {int i=10;p=&i;} void main() { //fun();  int i=10;p=&i; //cout //Sleep(1000); //cout cout cout } 结果:

zhangyulin54321的专栏 5899

指针?悬空指针? 一文带你搞懂!

???? 作者:Linux猿 ???? 简介:CSDN博客专家????,C/C++、面试、刷题、算法尽管咨询我,关注我,有问题私聊! ???? 关注专栏:C/C++面试通关集锦(优质好文持续更新中……)???? 目录 一、指针 二、悬空指针 2.1 情况一 2.2 情况二 2.3 情况三 指针悬空指针指针中常见的两个概念,本文结合实例讲解来讲解下。 一、指针 指针是指尚未初始化的指针,既不指向合法的内存空间,也没有使用 NULL/nullptr 初始化指针。 来看一个简单

Muti-Agent 1万+

指针悬垂指针

指针 指针:指向“垃圾”内存(不可用内存)指针 产生原因:指针创建时未初始化 int *p;//此时p为指针 解决办法:指针创建时对其进行初始化 int *p = NULL; 悬垂指针 悬垂指针所指向的空间已经被释放了,但是free后并没有修改指针为NULL,仍旧指向原空间。 解决办法:free后,将指针设为NULL。 char *p = (char *)malloc(12); free(...

chirrupy_hamal的博客 692

悬挂指针指针:如何避免常见内存问题

悬挂指针指针:如何避免常见内存问题

John_ToStr的博客 530

智能指针 相关概念

智能指针,unique_ptr, shared_ptr, weak_ptr 悬挂指针指针,内存泄漏相关概念

qq_56110001的博客 1918

基于python+gurobi的数值双层规划问题求解

该资源采用python编写,通过调用gurobi对数值双层优化问题进行求解,是学习双层规划的绝佳材料。

上一篇: 用JavaScript实现自己的DOM选择器
下一篇: 一名程序员的杂想
weixin_30711917
博客等级 码龄11年 123粉丝 0原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值