0

我们有一个大型 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,在此处找到)。

此方法的另一种实现和推理可在此处找到。

4

2 回答 2

0

从可执行文件中去除调试符号。每个实例 1k 可能不是 c'tor 的代码,而是调试符号。

于 2012-07-11T11:56:56.573 回答
0

这似乎是使用模板时最合乎逻辑和最精确的方式。正如Torsten Robitzki所建议的那样,尝试从可执行文件中剥离调试符号。

根据您的编译器,尤其是用于实时嵌入式系统的较旧的编译器,模板可能会迅速增大二进制文件的大小。如果是这种情况,有一些选项可以避免使用模板:

  • 实施分配策略。如果BufferString写得正确,那么它拥有的内存 ( m_buf) 可以在堆栈或堆上分配而不会引入泄漏。如果碎片和时间而不是内存泄漏是避免堆的主要原因,那么需要考虑许多专门用于缓解实时系统上的这些问题的分配模式,例如池或静态分配模式。
  • 如果必须避免堆,并且模板导致过多的膨胀,那么另一种选择是手动声明缓冲区并MyString单独声明。尽管我会尽量避免它,但宏可能会在可用性和可读性之间提供适当的折衷。例如,以下宏可用于声明自动变量:

    #define BUFFER_STRING(name, size)  \
      char name##buffer[size];         \
      MyString name(name##buffer, size)
    
于 2012-07-11T14:27:23.863 回答