巨大CString的C ++串联

时间:2018-08-08 15:54:38

标签: c++ concatenation c-strings

在遗留代码库中串联大型CString时遇到问题。 CString可以包含base64编码的文件,因此可能很大。这些CString在以下几点被串联:

result += CString(_T("Some smaller String")) + Huge_CString + _T("Some smaller String");

这导致了几种分配,因此我们得到了巨大的内存高峰。尽管这是针对不同文件在多个线程上并行完成的。如果他们都在一起,我将最终获得“内存异常”。

处理此问题的最佳方法是什么。如果我可以减少分配的数量,那将已经有所帮助。现在,我不是在寻找完美的解决方案,而是在寻找一种减少峰值的方法。

3 个答案:

答案 0 :(得分:4)

对于编辑大字符串,您可能希望使用非连续类型ropeunencoded_rope-可安全插入,写时复制或廉价插入的字符串类型的中间。

答案 1 :(得分:3)

我将建议使用与Remy Lebeau基本相同的东西,但是使用一些不同的功能。我不确定哪个版本的MFC / ATL引入了CString :: Preallocate函数,因此可能是您陷入了不具有此功能的MFC / ATL版本。

    CString result(_T("Initial string "));
    CString prefix(_T("Prefix string:"));
    CString suffix(_T(":Suffix string"));
    CString bigString(_T("This really isn't very big."));

    auto totalLength = result.GetLength() + prefix.GetLength() + bigString.GetLength() + suffix.GetLength();

    result.Preallocate(totalLength);

    result += prefix.GetString();
    result += bigString.GetString();
    result += suffix.GetString();

对CString :: GetString的调用可能有用也可能没有用。通过将每个子字符串附加到result,您可能会得到相同的分配行为。

答案 2 :(得分:2)

预先分配单个CString所需的串联长度,然后将数据从较小的字符串复制到其内部缓冲区中,例如:

CString Huge_CString = ...;
LPCTSTR ss1 = TEXT("Some smaller String");
LPCTSTR ss2 = TEXT("Some smaller String");

int ss1_len = lstrlen(ss1);
int huge_len = Huge_CString.GetLength();
int ss2_len = lstrlen(ss2);

int concat_len = ss1_len + huge_len + ss2_len;

CString Concat_CString;
PXSTR buffer = Concat_CString.GetBufferSetLength(concat_len);
CString::CopyChars(buffer, ss1, ss1_len);
buffer += ss1_len;
CString::CopyChars(buffer, Huge_CSString.GetBuffer(), huge_len);
buffer += huge_len;
CString::CopyChars(buffer, ss2, ss2_len);
Concat_CString.ReleaseBuffer(total_len);

// use Concat_CString as needed...