标签: dangling-pointer

当我访问它时,这个异步技巧会起作用还是状态会悬空?

我面临的情况是std::async完全异步启动操作会很好.

future<void> MyClass::MyAsyncFunc() {
    std::future<void> f = std::async(...);
    return f;
}  // The future goes out of scope, will block.
Run Code Online (Sandbox Code Playgroud)

问题是如果我不保存未来,该功能将在最后阻止.我希望这不会发生.

这将阻止在std::future函数范围的末尾调用它的析构函数:

shared_ptr<future<void>> MyClass::MyAsyncFunc() {
    auto shared_ftr = std::make_shared<std::future<void>>();
    *shared_ftr = std::async([shared_ftr]() {...});
    return shared_ftr;
}
Run Code Online (Sandbox Code Playgroud)

这可能有用吗?当我不将结果保存在变量中时会发生什么?

c++ multithreading asynchronous c++11 dangling-pointer

13
推荐指数
1
解决办法
1024
查看次数

在内在的lambda中悬空引用

我有一个内部lambda使用外部lambda的一个引用变量,如下所示:

int x=0;
auto outer=[&](){
   return [&](){
        x=5;
    };
};

auto inner= outer();
inner();
std::cout << x;
Run Code Online (Sandbox Code Playgroud)

试了一下.它运作良好.但是,我想确保这里没有悬空参考.在那儿?

c++ lambda c++11 dangling-pointer

13
推荐指数
2
解决办法
1440
查看次数

编写一个函数来释放指针并将其赋值为NULL

我在最近的一次采访中被问到这个问题,基本上是编写了一个函数来结合free的功能和赋值null.我用以下方式回答:

void main()
{
      int *ptr;
      ptr = new int;
      ptr = newdelete(ptr);
}

(int*) newdelete (int *ptr)
{
      delete(ptr);
      return NULL;
}
Run Code Online (Sandbox Code Playgroud)

因此在执行之后,当我从函数返回时,ptr本地main将保持空值newdelete.如果我刚刚NULL在newdelete函数中分配,则ptr本地newdelete将被取消,而不是ptr本地的main.

我认为我的解决方案是正确的,面试官也接受了.但是,他期待着其他一些答案.他坚持要求我不NULL从函数返回并仍然达到预期的效果.

有没有办法实现这一目标?我能想到的只是传递另一个参数,它是指向ptr本地指针的指针main,但我不明白为什么它比我做的更好!

c++ delete-operator dangling-pointer

11
推荐指数
2
解决办法
913
查看次数

有没有办法检查指针是否悬空?

我有一个代码,我使用指针访问一些数据块.在极少数情况下,数据块的一些成员是空的,因此指针变为悬空.事实上,我得到了正确的指针,但程序在尝试用指针做某事时崩溃了.

通常的建议是避免这种用法.但遗憾的是,我使用的框架要求我使用这种类型的数据访问方法.

有没有办法在用它做任何操作之前"检查"指针是否无效?显然,检查指针不等于NULL不起作用.我也试过这个:

try
{
    CString csClassName = typeid(*pMyPointer).name();  // Check error condition
    // The line below fails due to dangling pointer (data block is not valid).
    hr = pMyPointer->MyPointerMethod(); 
}
catch(bad_typeid)
{
    return E_FAIL;
}
catch(...)
{
    return E_FAIL;
}
Run Code Online (Sandbox Code Playgroud)

这是正确的方法吗?

c++ mfc pointers dangling-pointer

11
推荐指数
2
解决办法
6315
查看次数

检查悬空指针的值是安全的还是未定义的行为?

我们只能取消引用有效的指针,并且只能检查悬空内置指针指向的地址。我们无法访问它的值(它指向的对象地址中的值)。

int* ptr = nullptr;
if(ptr) // != 0x00000000
   std::cout << *ptr << '\n';

ptr = new int(1000);

if(ptr) // != 0x00000000
   std::cout << *ptr << '\n';

delete ptr; // still pointing at the address of that dynamic object but that object has been destroyed.

if(ptr) // succeeds or undefined behavior?
   std::cout << *ptr << '\n'; // of course UB here
Run Code Online (Sandbox Code Playgroud)

所以我很清楚,但我关心的只是检查指针值是否安全或产生 UB?if(ptr)。因为我们假设我没有像 那样访问该地址中的值std::cout << *ptr

c++ pointers dangling-pointer

11
推荐指数
1
解决办法
805
查看次数

GCC编译C/C++的最强硬选项是什么?

哪些GCC选项可以最好地防止内存损坏漏洞,如缓冲区溢出和悬空指针?GCC是否提供任何类型的ROP链缓解?是否存在性能问题或其他问题会妨碍此GCC选项在生产中使用关键任务应用程序?

我正在查看Debian强化指南以及GCC Mudflap.以下是我正在考虑的以下配置:

-D_FORTIFY_SOURCE=2
-fstack-protector --param ssp-buffer-size=4
-fPIE -pie
-Wl,-z,relro,-z,now (ld -z relro and ld -z now)
Run Code Online (Sandbox Code Playgroud)

是否可以对这组选项进行任何改进?假设最新版本的GCC,如果你知道任何很酷的即将推出的功能,请告诉我!

c++ security gcc buffer-overflow dangling-pointer

10
推荐指数
1
解决办法
1618
查看次数

悬挂指向多态类的指针会导致未定义的行为.它是否可以成为任何可以想象的腐败的根源?

我知道Undefined Behavior,一旦发生,就不可能再考虑代码了.我完全相信.我甚至认为我不应该过多地理解UB:一个理智的C++程序不应该与UB,Period一起玩.

但是为了让我的同事和经理们相信它的真正危险,我试图找到一个具体的例子,我们在产品中有一个错误(他们认为这不是危险的,最糟糕的是它总会崩溃访问违规).


我主要担心的是在悬挂指向多态类的指针时调用虚拟成员函数.

删除指针时,Windows操作系统将在堆块的标题中写入几个字节,并且通常还会覆盖堆块本身的第一个字节.这是跟踪堆块的方法,将它们作为链表进行管理......操作系统的东西.

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


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

当代码中的某个地方,我们称之为:

void test(A * pA)   
{
    # here we do not know that pA is dangling pointer
    # that memory address has been deleted by another thread, in another part of the code
    pA->SomeVirtualFunction();
}
Run Code Online (Sandbox Code Playgroud)

我正确地说:

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

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

c++ undefined-behavior dangling-pointer

10
推荐指数
1
解决办法
199
查看次数

co_yield 指向局部协程变量的指针是否不安全?

众所周知,返回指向堆栈变量的指针通常是一个坏主意:

int* foo() {
  int i = 0;
  return &i;
}

int main() {
  int* p = foo();
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我的理解是 被int破坏了,p悬空指针也被破坏了。

我想知道这在多大程度上适用于 C++20 新引入的协程:

generator<span<byte>> read(stream& s) {
  array<byte, 4096> b;
  while (s.is_open()) {
    const size_t n = s.read_some(b);
    co_yield span(b, n);
  }
}

int main() {
  stream s;
  for (span<byte> v : read(s)) {
    /* ... */
  }
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,read协程生成span本地缓冲区的视图b。在内部,该视图存储一个指向缓冲区的指针。v当与范围循环体一起使用时,该指针是否会悬空for

对于上下文,第二个示例中的协程代码是根据我自己的项目中的代码建模的。在那里,AddressSanitizer 以“释放后使用”错误结束程序。通常我认为这足以回答我的问题,但由于此时协程开发仍在进行中(我的项目正在使用boost::asio::experimental::coro,强调“实验”),我想知道该错误是否是由以下错误引起的generator …

c++ coroutine dangling-pointer c++20 c++-coroutine

10
推荐指数
1
解决办法
244
查看次数

在 C++ 中进行常量求值时,悬空指针可以等于有效指针吗?

在 C++17 中的常量表达式求值期间,编译器是否应考虑寻址有效对象的任何指针与在其生命周期结束后寻址对象的任何指针不相等?

例如:

constexpr auto f(int * x = nullptr) {
    int c = 0;
    auto p = &c;
    if ( x == p )
        throw "unexpected";
    return p;
};

int main() {
    static_assert( f( f() ) );
}
Run Code Online (Sandbox Code Playgroud)

这里函数的内部调用f()返回一个悬空指针,该指针被再次传递给f。我相信条件x == p一定是false因为xis 是一个悬空指针并且p是一个有效指针,在 Clang 中确实如此。但在 GCC 中,条件得到满足,并且由于 ,常量求值失败throw。演示: https: //gcc.godbolt.org/z/ehcMro17q

这是一种未定义的或实现定义的行为,还是其中一个编译器是错误的?

c++ language-lawyer constexpr dangling-pointer c++17

9
推荐指数
1
解决办法
279
查看次数

简单,高效的弱指针,在取消分配目标内存时设置为NULL

是否有一个简单,有效的弱/保护指针?我需要多个指向同一对象的指针,当删除对象时,这些指针都会自动设置为NULL.有一个"主"指针始终用于删除对象,但可能有几个其他指针引用同一对象.

以下是一些不太符合我需求的解决方案:

  • QPointer:我没有开发QT应用程序; 我不希望从QObject中包含这个libary/derived.
  • boost :: weak_ptr:访问解除分配的对象时抛出异常.我的情况太贵了:测试弱指针应该是正常的; 当弱指针不再有效时,我打算做一些手动清理. 更新:可以在不抛出异常的情况下测试weak_ptr
  • 低开销弱指针:这非常接近我正在寻找的东西,除了我不喜欢这样的事实"只要你不分配2**sizeof(int)次,这个方案只能保证工作同一个地方."

为什么我需要这些弱/保护指针: 我有一个游戏对象列表的游戏.一些对象依赖于其他对象,例如与游戏实体相关联的调试/统计对象.调试/状态对象显示有关游戏实体的有用信息,但它只在游戏实体存在时才有意义.因此,如果删除了游戏实体,则debug/stats对象应实现此功能并自行删除.(另一个想法是跟踪导弹:它可能会搜索新目标,而不是自行删除.)

我希望将调试/统计逻辑与游戏实体分开.游戏实体不应该知道附加了调试/统计对象.虽然我更喜欢弱/保护指针的答案,但我也欢迎不同的方法来处理我的具体任务.我想我可能必须实现一个跟踪对象生命周期的游戏对象管理器,并使用句柄而不是内存地址的原始指针.

我正在用C++开发.

c++ pointers dangling-pointer

8
推荐指数
2
解决办法
4253
查看次数