在遗留代码库中串联大型CString时遇到问题。 CString可以包含base64编码的文件,因此可能很大。这些CString在以下几点被串联:
result += CString(_T("Some smaller String")) + Huge_CString + _T("Some smaller String");
这导致了几种分配,因此我们得到了巨大的内存高峰。尽管这是针对不同文件在多个线程上并行完成的。如果他们都在一起,我将最终获得“内存异常”。
处理此问题的最佳方法是什么。如果我可以减少分配的数量,那将已经有所帮助。现在,我不是在寻找完美的解决方案,而是在寻找一种减少峰值的方法。
答案 0 :(得分:4)
对于编辑大字符串,您可能希望使用非连续类型rope
或unencoded_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...