【问题标题】:Finding out the largest size of several objects for placement new找出用于放置新的几个对象的最大尺寸
【发布时间】:2016-05-24 02:53:10
【问题描述】:

所以我正在开发一个内存非常有限且没有 MMU 的小型 ARM 嵌入式系统。我有几个对象需要动态分配给不同的函数,这些函数都继承自同一个超类,但执行不同的函数并且可能大小不同。我没有足够的可用内存在启动时将它们全部实例化并将它们留在原处。

举个例子,我可能有类似这样定义的对象:

class Waveform1 : public OutputStream
class Waveform2 : public OutputStream
class Waveform3 : public OutputStream

并且子类将具有不同的大小,因为有些子类的方法和私有变量可能比其他的少,但很可能没有一个比其他任何一个大得多。

我想做的是分配一个缓冲区以在系统启动时与放置 new 一起使用,该缓冲区大到足以包含最大的已定义对象。然后我应该能够毫无问题地在那里实例化和销毁对象,因为它总是足够大以容纳所需的最大对象。我希望自动处理这个问题,因为随着系统设计的进行,新对象可能会添加到列表中。

有没有一种规范的方法来完成这个,所以看起来我知道我在做什么?

【问题讨论】:

  • std::max({sizeof(Waveform1), sizeof(Waveform2), sizeof(Waveform3)}) ?
  • @Jarod42 Err...我忘了说,STL 可能不可用。 :(
  • max 应该足够简单,可以重新实现。
  • 我会看看 - 通过预处理来处理这绝对是我想要的。
  • constexpr够了吗?

标签: c++ embedded placement-new


【解决方案1】:

我过去所做的是使用 char 数组和我需要存储在其中的所有类型的联合。好处是缓冲区将正确对齐。

类似:

class MyClass {
    public:
        union {
            char buffer[1];
            ClassA a;
            ClassB b;
        };
    MyClass() {}
    ~MyClass() {}
};

请注意,您可以省略 char buffer[1] 并将 new 放置在联合的类成员上,例如 new (&a) ClassA。另请注意,如果 ClassA 或 ClassB 是除 POD 之外的任何东西,那么这只适用于 C++11。

现在,事实证明,我实际上所做的与我记得所做的不同。可能是因为我必须支持 C++03。在我的实际代码中,我这样做了:

char DECLARE_ALIGN(8) buffer[ sizeof(int*) * 8 ];

DECLARE_ALIGN 是:

#  define DECLARE_ALIGN(x)  __attribute__((aligned(x)))

或者

# define DECLARE_ALIGN(x) __declspec( align(x) )

然后在代码的后面,在实际分配对象的函数中,在我将缓冲区作为指针传递,将 sizeof(buffer) 作为 buffer_len 传递之后:

assert( buffer==0 || buffer_len >= sizeof(BTreeNodeWriter_X<X>) );
assert( buffer==0 || buffer_len >= sizeof(BTreePackedNodeWriter_X<X>) );

【讨论】:

  • 为什么是char buffer[1]?要做new (u.buffer) WaveFormX ?
  • @Jarod42 是的,新展示位置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-24
  • 2013-04-30
  • 1970-01-01
  • 2015-01-26
  • 2012-08-18
  • 2017-03-27
  • 2017-05-05
相关资源
最近更新 更多