其他分享
首页 > 其他分享> > C就地构造和随后的破坏:我如何获得正确的指针?

C就地构造和随后的破坏:我如何获得正确的指针?

作者:互联网

免责声明:这是一个细致入微的C问题,与严格阅读C规范有很大关系.

在C中,使用就地构造的传统方法是:

void * pStorage = myPooledAllocationFunction ( /*pool number*/1 ) ; // allocate from pool number 1, for example
MyClass * p = new (pStorage) MyClass () ;

然而,重要的是要注意reinterpret_cast< void *> (p)不一定等于pStorage.

旁注:当我刚刚读到这个贴片时,我感到很沮丧,因为它真的只是说“请用这个额外的参数调用operator new”,而传统的使用它的方法恰好在C中有一个默认的实现.

我相信解除分配这个新创建的对象的传统方法是这样的:

p->~MyClass() ;
myPoolDeallocationFunction ( /*pool number*/1 ) ; // deallocate pool 1 in its entirety

这假设你能够做到这一点.但是如果你不是呢?如果你需要从p返回原始指针怎么办?

这有效吗?

p->~MyClass() ;
myPooledDeallocationFunction ( static_cast<void*> ( p ) ) ;

C规范(C 2003:5.2.9.10)规定使用static_cast从MyClass *转换为void *然后再转换回MyClass *是有效的.

还有另一个提及(C 2003:3.8.5)与此相关,指定您可以在调用析构函数之后但在释放内存之前,为该指针执行一组非常具体的操作.出于我们的目的,我们关心的是它包括将其转换为void *(这是有效的,因为旧指针“指向有效的内存”).

它没有说明该空隙*是否是用于就地构造的原始空隙*.

那么:如何从结果指针中获取用于就地构造的原始指针?

解决方法:

您可以使用dynamic_cast< void *>从基类检索原始指针.结果指针将始终指向派生程度最高的类,a.k.a.整个对象.

据我所知,pStorage和p是不同的地址是非法的.

标签:c,pointers,constructor,specifications
来源: https://codeday.me/bug/20190824/1708604.html