首页 > 解决方案 > shared_ptr :没有实例化的分配

问题描述

我正在编写一个代码,我必须管理一个了不起的设计。

我现在遇到的问题是两个类之间的循环依赖:类A需要实例化B类,而类B需要shared_ptr实例化A类。而A是由继承B的类C构建的……所以C传递*this给A的构造函数来构建它。是的,我知道,这太可怕了。但我无法改变这一点(有比 A、B 和 C 更多的类......)。

尽管如此,我还是尝试将所有这些类分开以便能够测试它们(今天,它们都在一个测试类中的一个块中进行了测试)。

对于测试,我试图只考虑 A 类和 B 类,而不是 C。

我试图在operator new不构建任何对象的情况下为 A 分配内存(因为我需要 B ...)。然后我shared_ptr从这个分配的内存构建 a 到 A ,并通过传递 this 来构建 B shared_ptr。现在我已经实例化了 B,我可以将它传递给 A 以使用放置 new 来实例化它,方法是使用shared_ptr::get().

它确实编译。但是在 A 实例化的某个地方,shared_ptr分配了一个指针但没有任何对象的指针被它的父类之一复制,我在shared_ptr(析构函数)中崩溃了。

我想这是因为分配,但我不明白为什么。在询问您可能导致此崩溃的原因之前,我想知道您是否认为使用operator new然后放置新闻在我的用例中有意义。谢谢。

这是有关此内存管理的一段代码:

#include <iostream>
#include <memory>
 
struct Class_A
{
    int a = 1;
    int b = 2;
};

int main()
{
    void *rawMemory = operator new(sizeof(Class_A));
 
    std::shared_ptr<Class_A> foo1 = std::make_shared<Class_A>();
    
    std::shared_ptr<Class_A> foo2(static_cast<Class_A*>(rawMemory));
 
    std::cout << foo2->a << std::endl;
    std::cout << foo2->b << std::endl;
 
    foo1 = foo2;
 
    new (foo2.get()) Class_A();
 
    std::cout << foo2->a << std::endl;
    std::cout << foo2->b << std::endl;
 
    return 0;
}

标签: c++shared-ptrnew-operatorcircular-dependency

解决方案


我发现了问题。

在我的代码中,为了做operator new,我传递给了sizeof()一个decltype变量的 a 。但如果是decltype,shared_ptr而不是元素类型。所以我因错误而崩溃:
free(): invalid size

我现在使用decltype(myVariable)::element_type,它确实有效。

因此,如果您不能改变遗留代码的不良概念,那么示例代码最终是一个“好”的黑客。


推荐阅读