了解C ++指针的生命周期/僵尸指针

问题描述 投票:1回答:1

看完CppCons Will Your Code Survive the Attack of the Zombie Pointers?之后,我对指针的寿命有些困惑,需要澄清一下。

首先要有一些基本的了解。如果有任何错误意见,请纠正我:

int* p = new int(1);
int* q = p;
// 1) p and q are valid and one can do *p, *q
delete q;
// 2) both are invalid and cannot be dereferenced. Also the value of both is unspecified
q = new int(42); // assume it returns the same memory
// 3) Both pointers are valid again and can be dereferenced

我为2感到困惑。显然,它们不能被取消引用,但是为什么不能使用它们的值(例如,将它们与另一个,甚至不相关且有效的指针进行比较?)在25:38中进行了说明。我在cppreference上找不到任何相关信息,这是我从中获得3)的地方。

注:返回相同内存的假设不能一概而论,因为它可能会或可能不会发生。对于此示例,应该认为它“随机地”返回了与视频示例相同的内存,并且(也许是)以下代码中断所需的内存。

可以将LIFO列表中的多线程示例代码模拟为一个线程:

Node* top = ... //NodeA allocated before;
Node* newnodeC = new Node(v); 
newnodeC->next = top;
delete top; top = nullptr;
// newnodeC->next is a zombie pointer
Node* newnodeD = new Node(u); // assume same memory as NodeA is returned
top = newnodeD;
if(top == newnodeC->next) // true
  top = newnodeC;
// Now top->next is (still) a zombie pointer

这应该是有效的,除非Node根据]下的规则包含非静态const成员或引用>

如果在另一个对象占用的地址上创建了一个新对象,则所有指针,引用和原始对象的名称将自动引用该新对象,并且一旦新对象的生命周期开始,可以用于操作新对象,但前提是必须满足以下条件[它们]

那么,为什么这是僵尸指针,又应该是UB?

以上的(单线程)压缩代码是否可以通过newnodeC->next = std::launder(newnodeC->next)从[]开始固定(在有const成员的情况下

如果不满足上面列出的条件,则仍然可以通过应用指针优化障碍std :: launder获得指向新对象的有效指针

我希望它能够修复“僵尸指针”,并且编译器不会发出分配指令,而只是将其视为优化障碍(例如,当函数内联并且再次访问const成员时)]

所以总而言之:我以前从未听说过“僵尸指针”。我是否正确,除非重新分配了指针或在那里重新创建了具有相同对象类型的内存,否则无法使用任何指向已销毁/删除对象的指针(用于读取[指针值]和取消引用[指针的读取])。没有const / reference成员)?不能通过C ++ 17 std::launder修复吗? (禁止多线程问题)

在观看了CppCons之后,您的代码能否幸免于僵尸指针的攻击?我对指针的寿命有些困惑,需要澄清一下。首先是一些基本的认识。请更正...

c++ pointers lifetime object-lifetime
1个回答
0
投票

我不同意:

© www.soinside.com 2019 - 2024. All rights reserved.