找出几个对象的最大尺寸以放置新的
Finding out the largest size of several objects for placement new
所以我正在开发一个内存非常有限且没有 MMU 的小型 ARM 嵌入式系统。我有几个对象需要为不同的函数动态分配,这些函数都继承自同一个超类,但执行不同的函数并且可能大小不同。我没有足够的可用内存来在启动时将它们全部实例化并将它们留在原地。
举个例子,我可能定义了如下对象:
class Waveform1 : public OutputStream
class Waveform2 : public OutputStream
class Waveform3 : public OutputStream
并且子类将具有不同的大小,因为有些子类的方法和私有变量可能比其他子类少,但可能 none 将比其他任何一个都大得多。
我想做的是分配一个缓冲区以在系统启动时与 placement new 一起使用,该缓冲区足够大以包含最大的已定义对象。然后我应该能够毫无问题地实例化和销毁那里的对象,因为它总是足够大以容纳所需的最大对象。我希望自动处理此问题,因为随着系统设计的进行,新对象可能会添加到列表中。
有没有一种规范的方法可以做到这一点,所以看起来我知道自己在做什么?
我过去所做的是使用 char 数组和我需要存储在其中的所有类型的联合。好处是缓冲区将正确对齐。
类似于:
class MyClass {
public:
union {
char buffer[1];
ClassA a;
ClassB b;
};
MyClass() {}
~MyClass() {}
};
请注意,您可以省略 char buffer[1]
并将新的位置放在联盟的 class 成员上,例如 new (&a) ClassA
。另请注意,如果 ClassA 或 ClassB 是 PODs 以外的任何内容,则这仅适用于 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>) );
所以我正在开发一个内存非常有限且没有 MMU 的小型 ARM 嵌入式系统。我有几个对象需要为不同的函数动态分配,这些函数都继承自同一个超类,但执行不同的函数并且可能大小不同。我没有足够的可用内存来在启动时将它们全部实例化并将它们留在原地。
举个例子,我可能定义了如下对象:
class Waveform1 : public OutputStream
class Waveform2 : public OutputStream
class Waveform3 : public OutputStream
并且子类将具有不同的大小,因为有些子类的方法和私有变量可能比其他子类少,但可能 none 将比其他任何一个都大得多。
我想做的是分配一个缓冲区以在系统启动时与 placement new 一起使用,该缓冲区足够大以包含最大的已定义对象。然后我应该能够毫无问题地实例化和销毁那里的对象,因为它总是足够大以容纳所需的最大对象。我希望自动处理此问题,因为随着系统设计的进行,新对象可能会添加到列表中。
有没有一种规范的方法可以做到这一点,所以看起来我知道自己在做什么?
我过去所做的是使用 char 数组和我需要存储在其中的所有类型的联合。好处是缓冲区将正确对齐。
类似于:
class MyClass {
public:
union {
char buffer[1];
ClassA a;
ClassB b;
};
MyClass() {}
~MyClass() {}
};
请注意,您可以省略 char buffer[1]
并将新的位置放在联盟的 class 成员上,例如 new (&a) ClassA
。另请注意,如果 ClassA 或 ClassB 是 PODs 以外的任何内容,则这仅适用于 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>) );