问题标签 [dangling-pointer]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
1441 浏览

c++ - 对于进程间 COM 对象,在不使用 QueryInterface 的情况下将 IDispatch* 转换为 IUnknown* 是否安全?

在处理进程间COM对象时,不使用将 aIDispatch*转换为a 是否安全?IUnknown*QueryInterface

这里我们的IDispatch对象来自另一个进程OtherProcess.exe。我的一位同事说我应该打电话QueryInterface给.IDispatchIUnknown

目前我正在做:

我对他的建议的问题:我正在处理 OtherProcess.exe 崩溃或被杀死的情况(访问冲突)。似乎调用任何函数,如封装来自不再存在的 OtherProcess.exeInvoke的任何对象的任何函数都会引发这些访问冲突(编辑:评论和答案表明这个最新的假设是完全错误的!)。IDispatch

这就是我试图保护::CoIsHandlerConnected(pIUnknown);采用IUnknownas 参数的应用程序测试的原因。

但是通过调用QueryInterfaceIDispatch就像我的同事建议我做的那样,我害怕退回到我试图解决的同一个问题:这IDispatch处理一个不再存在的对象,并且QueryInterface对于一个 IUnknown将只是未定义的行为都一样(再次编辑,这个假设也是错误的)。

当我只是做演员时,我真的错了吗?处理死进程间COM对象的常用方法是什么?

这是 OAIdl.h 中定义的开始IDispatch,它被声明为派生自IUnknown.

0 投票
1 回答
375 浏览

c++ - 指向多态类的悬空指针会导致未定义的行为。它真的可以成为任何可以想象的腐败的根源吗?

我知道未定义的行为一旦发生,就不可能再考虑代码了。我确信,完全。我什至认为我不应该深入了解 UB:一个理智的 C++ 程序不应该与 UB 一起玩,期间。

但是为了让我的同事和经理相信它的真正危险,我试图找到一个具体的例子,我们在产品中确实存在一个错误(他们认为这并不危险,最坏的情况下它总是会崩溃访问冲突)。


我主要关心的是在指向多态类的悬空指针上调用虚拟成员函数。

当一个指针被删除时,windows操作系统会在堆块的头部写入几个字节,通常也会覆盖堆块本身的第一个字节。这是跟踪堆块,将它们作为链表管理的方式......操作系统的东西。

虽然它没有在 C++ 标准中定义,但多态性是使用虚拟表 AFAIK 实现的。在 windows 下,虚拟表的指针位于堆块的第一个字节中,给定一个只继承一个基类的类。(多继承可能会更复杂,但我不会考虑这个。我们只考虑基类A,以及几个B,C,D继承A)。


现在让我们考虑我有一个指向 A 的指针,它被实例化为 D 对象。并且该 D 对象已在代码中的其他位置被删除:因此堆块现在是一个空闲堆块,并且它的第一个字节已被覆盖,因此虚拟表指针几乎随机指向内存中的某个位置,比方说地址0x01234567

在代码中的某个地方,我们调用:

我说得对吗:

  • 运行时会将地址处的内存解释0x01234567为虚拟表
  • 如果在像 vtable 一样错误地解释这个内存地址时,它没有进入禁止的内存区域,就不会有任何访问冲突
  • 被误解的虚拟表将为要执行的虚拟函数提供一个随机地址,比方说0x09876543
  • 随机地址处的内存0x09876543将被解释为有效的二进制代码,并执行为真实的
  • 这可能导致任何可以想象的腐败

我不想夸大其词,以便说服。那么,我所说的是正确的、可能的和可能的吗?

0 投票
1 回答
26 浏览

pointers - 引用是否解决了指针问题?

嗨,我很困惑使用参考。如果我们使用引用而不是指针,它是否解决了悬空甚至内存泄漏问题?

0 投票
1 回答
411 浏览

delphi - Delphi中的悬空指针

我没有使用接口(所以对象没有引用计数)。这些对象可能被许多其他人引用,我需要处理悬空指针。FreeAndNil() 不能解决多个引用的问题。我需要当一个对象被销毁时,所有引用它的指针都会自动设置为 nil。或者,它可能类似于 C++ 中 std::weak_ptr 的 Expired() 方法。

我可以实现一个“弱智能指针”来做到这一点,但我不确定它是否是一个过于复杂的实现。你建议另一种解决方案吗?这是我正在考虑的未经测试的可能解决方案:

0 投票
5 回答
5316 浏览

c++ - 删除指针和将其设置为 nullptr 有什么区别?

是说delete pointerpointer = nullptr一样吗?可能不会,但后者会释放内存吗?delete pointer; pointer = nullptr/呢pointer = nullptr; delete pointer?如果需要,为什么不使用它来提供一种安全的方法来提前删除指针,因为它们通常会在其他时间被删除并导致正常删除时出错?

0 投票
6 回答
2461 浏览

c++ - 为什么没有 unique_ptr::operator*() 的安全替代方案?

std::vector将成员函数at()作为 的安全替代方法operator[],因此应用绑定检查并且不创建悬空引用:

但是,std::unique_ptr缺少相应的功能:

如果有这样一个安全的替代方案,那就太好std::unique_ptr了,比如成员ref()(and cref()),它从不返回悬空引用,而是抛出异常。可能的实现:

标准不提供这种东西有什么好的理由吗?

0 投票
3 回答
162 浏览

c++ - 当数据写入由不同数据类型的悬空指针指向的内存位置时会发生什么

如果指针数据类型与新输入的数据相同,我想它不会出错,但如果指针具有不同的数据类型,我们就会出现类型不匹配。我想知道编译器是否会对此做些什么(比如先删除悬空指针),或者只是给出一个错误。

0 投票
3 回答
550 浏览

c - 悬空指针示例混淆

为什么下面的例子不正确?为什么它不显示一个悬空指针?我的老师说它没有显示悬空指针。提前致谢!

这里也一样。为什么以下示例不演示内存泄漏

0 投票
1 回答
512 浏览

c++ - flatbuffers:是否可以通过根指针删除缓冲区

我开始使用 flatbuffer 库。但是在删除缓冲区时,有一件事情让我感到不舒服。我不知道如何通过它的根指针元素删除缓冲区。如果这是可能的,根指针可以获取分配空间的所有权,我不必担心生命周期问题(悬空根指针,内存泄漏,......)

问:是否有可能(可能在某些限制下,因为怪物是不可变的,等等)写类似 delete_buffer 的东西

0 投票
1 回答
1084 浏览

c++ - C++ 状态模式实现:指向状态机的指针机制变得无效?

在尝试从“Head First Design Patterns”一书中实现一个简单的状态模式示例时,我遇到了一种让我觉得很奇怪的情况。请注意,这个问题不是关于正确实现模式,而是关于理解导致观察到的行为的底层机制。

机器“Gumball_machine”应该有几种可能的状态(No_quarter_stateHas_quarter_stateSold_out_state等),在运行时通过虚拟函数调用将行为委托给这些状态。这些状态是从一个抽象基类公开继承的StateGumball_machine有一个std::unique_ptr<State>State类本身是一个指向 的原始指针Gumball_machine(因为没有假定所有权)。

当满足某些条件时会发生状态转换,它们通过分配新的具体状态类并将所有权转移给Gumball_machine.

(我将在本文末尾发布一些代码示例,因为我想先“切入正题”。)

有一种情况,在切换状态后,在同一个函数中,另一个函数被调用:

是指向的machine_指针,是指向具体状态的.Gumball_machinestate_std::unique_ptr<State>Has_quarter_state

如果我声明临时指针ptr并调用Gumball_machine::dispense(),就没有问题。但是,如果我简单地调用machine_->dispense()valgrind 将显示无效读取(错误消息将在下面显示)。

而这个我真的不明白。ptr并且machine_应该引用同一个Gumball_machine实例,直到程序结束才应该被销毁。Has_quarter_state(或者更确切地说是父类“State”)只有一个没有所有权的原始指针。

现在想来,大概是因为-reset会导致实例unique_ptr占用的内存被释放。Has_quarter_state这可能意味着任何后续操作,即对 的函数调用Gumball_machine::dispense(),都会导致未定义的行为。这个假设正确吗?如果内存地址 ( &memory_ == &ptr) 没有改变,为什么我调用ptr->dispense()or会有什么不同machine_->dispense()

我觉得内存管理有一些我仍然不明白的复杂性。希望你能帮我把事情弄清楚。

下面我将发布重现此代码的代码(“不正确”版本)和 valgrind 给我的错误消息(使用--leak-check=full, --leak-kinds=all)。

clang++ -std=c++14 -stdlib=libc++代码通过使用 clang 3.6.0编译

现在对于实际代码(大大简化为一个最小的示例):

Gumball_machine.hpp:

Gumball_machine.cpp:

状态.hpp:

状态.cpp:

Has_quarter_state.hpp:

Has_quarter_state.cpp:

已售状态.hpp:

已售状态.cpp:

编辑: main.cpp

最后是 valgrind 输出:

预先感谢您的帮助!