【问题标题】:Flexible array member in class with polymorphism具有多态性的类中的灵活数组成员
【发布时间】:2020-07-25 01:54:06
【问题描述】:

在 C99 中你可以有类似的东西

struct foo
{
    int a;
    int data[];
}; 

然后用foo* f=(foo*)malloc(sizeof(foo)+n) 分配一个结构体,其中数组的长度为n

当类是具有虚函数的子类时,可以在 C++ 中做类似的事情吗?

就像 foo 是 bar 的子类,然后执行类似 std::unique_ptr<bar> f= std::unique_ptr<foo>((foo*)malloc(sizeof(foo)+n)) 的操作

我知道该代码不起作用,因为释放内存将使用 delete 完成,但分配是使用 malloc 完成的

【问题讨论】:

  • 在 C++ 中使用原始动态内存分配(malloc() 或运算符new)被认为是不好的做法。考虑使用标准容器,例如std::vector<int>,它将为您提供动态分配的 - 小心 - 一组可调整大小的ints(因为它在后台进行动态内存分配,而不是您直接进行)。如果您确实必须使用malloc() 来分配内存,您可以使用std::unique_ptr<>,但提供一个(可选)使用free() 的删除器。 malloc() 与 C++ 中的类不兼容,特殊情况除外。

标签: c++ c++11 polymorphism flexible-array-member


【解决方案1】:

不,按照标准规则是不可能的。 C++ 中根本不允许使用可变长度数组和灵活数组成员,例如您在示例中显示的。也没有等效或替代方案。

另外,malloc 根本不能用于在 C++ 中创建对象。只有具有正确类型的new 才能动态创建该类型的对象。如果假装创建了给定类型的对象,则其他所有内容都是不允许的,并且会导致未定义的行为。

自 C++20 以来,对于某些类型的对象,上述规则有一些例外情况,这些对象可以隐式创建,但是,对象的大小在编译时由其类型固定,不能在全部。

为一个对象过度分配永远不会导致额外的存储成为对象的一部分,并且永远不允许像访问它一样访问它。

【讨论】:

    【解决方案2】:

    可变长度数组实际上并不是 C++ 标准的一部分,而是编译器扩展。但是,如果你真的想使用它们,我的意思是,用malloc分配对象,你需要使用placement new来调用构造函数,并像f->~bar()之前手动调用析构函数(应该是虚拟的)打电话给free。由于malloc 为初始化对象生成了一个指向所需大小的内存的指针,因此这不应产生未定义的行为。

    【讨论】:

      猜你喜欢
      • 2020-04-13
      • 1970-01-01
      • 2012-11-22
      • 1970-01-01
      • 2020-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-16
      相关资源
      最近更新 更多