我们有一个大型的C ++实时程序,它使用不同大小的缓冲区(例如char str[500]
)来存储字符串。
由于我们过去曾有过一些内存泄漏,我们希望用MyString
类来包装字符串,这个类将使用缓冲区和大小进行初始化。
问题是如何高效,轻松地将缓冲区和包装器分配在一起,同时保持缓冲区作为类的一部分进行分配,而不是从堆中分配(参见下一个示例)。
我尝试过以下方式使用模板:
template <unsigned int N>
class BufferString : public MyString
{
public:
BufferString() : MyString(m_buf, N) { }
char m_buf[N];
};
因此可以将其分配为类成员或自动变量:
class SomeClass
{
BufferString<500> m_str; // Need the buffer to be allocated in SomeClass
};
void foo()
{
BufferString<350> str; // Need the buffer to be allocated on the stack
}
但是,使用此解决方案,可执行文件大小会大幅增加,每个模板实例大约1kB(可能是由于构造函数的编译)。
有更好的方法吗?
感谢。
fixed_char_buf
(由John Panzer发现here)。
找到此方法的另一种实现和推理here。
答案 0 :(得分:0)
从可执行文件中删除调试符号。每个实例1k可能不是c'tor的代码,而是调试符号。
答案 1 :(得分:0)
这似乎是使用模板时最合乎逻辑且最精确的方式。正如Torsten Robitzki所建议的那样,尝试从可执行文件中删除调试符号。
根据您的编译器,特别是实时嵌入式系统的旧编译器,模板可以快速膨胀二进制大小。如果是这种情况,有一些选项可以避免模板:
BufferString
,那么它拥有的内存(m_buf
)可以在堆栈或堆上分配,而不会引入泄漏。如果碎片和时间,而不是内存泄漏,是避免堆的主要原因,那么有许多分配模式需要考虑,专门用于缓解实时系统上的这些问题,例如池或静态分配模式。如果必须避免堆,并且模板导致过多的膨胀,那么另一种选择是手动声明缓冲区和MyString
。虽然我会尽可能地避免它,但宏可以在可用性和可读性之间提供适当的折衷。例如,以下宏可用于声明自动变量:
#define BUFFER_STRING(name, size) \
char name##buffer[size]; \
MyString name(name##buffer, size)