我想在没有新的内存分配和复制的情况下在C或C ++中连接2个字符串。有可能吗?
可能的C代码:
char* str1 = (char*)malloc(100);
char* str2 = (char*)malloc(50);
char* str3 = /* some code that concatenates these 2 strings
without copying to occupy a continuous memory region */
然后,当我不再需要它们时,我就这样做了:
free(str1);
free(str2);
或者如果可能的话,我希望在C ++中使用std::string
或char*
来实现相同的目标,但使用new
和delete
(可能void operator delete ( void* ptr, std::size_t sz )
在str3上运算符(C ++ 14)。
关于字符串连接有很多问题,但是我没有找到一个问题相同的问题。
答案 0 :(得分:7)
不,不可能
在C中,malloc操作返回彼此没有关系的内存块。但在C语言中,字符串必须是连续的字节数组。因此没有办法在不复制的情况下扩展str1,更不用说连接了。
对于C ++,可能会对绳索感兴趣:See this answer。
绳索以不必连续的块分配。这支持O(1)连接。但是,访问器使它显示为单个字节串。我确定将绳索转换回std :: string或C风格的字符串会占用一个副本,但这可能是你想要的最接近的。
此外,担心复制几个字符串的成本可能是一个不成熟的优化。除非您移动批次数据,否则无关紧要
答案 1 :(得分:2)
通过编写自己的字符串数据结构,可以实现文本连接。 C ++比C更容易。
struct My_String
{
std::vector<char *> text_fragments;
};
您必须基于此数据结构实现所有文本操作和搜索算法。 C库中的任何内容都不能应用于My_String
结构。 C ++中的std::string
不兼容。
其中一个问题是如何处理文本修改。如果其中一个文本片段是常量文字(无法修改),则需要先复制它才能进行修改。但复制是违背要求的。 : - (
答案 2 :(得分:1)
C中的“字符串”是一个字符数组,末尾有一个空字符。数组是“一种数据结构,可以让你在内存中存储一个或多个连续元素”。 GNU C reference
如果不复制其中一个数组,则无法连接两个不在连续内存块中的数组。但是,您无需分配新内存即可。 E.g。
char* str1 = malloc(100); // size 100 bytes, uninitialised
str1[0] = '\0'; // string length 0, size of str1 100
strcat(str1, "a"); // string length 1, size of str1 still 100
strcat(str1, "b"); // string length 2, size of str1 still 100
如果您想要检索2个字符串的字符,就好像它们是没有复制或重新分配的字符串一样。这是一个示例函数(简单示例,不要在生产代码中使用)
char* str1 = (char*)malloc(100);
char* str2 = (char*)malloc(50);
char get_char(int i) {
if (i > 0 && i < 100) {
return str1[i];
}
if (i >= 100 && i < 150) {
return str2[i-100];
}
return 0;
}
但在这种情况下,您无法使用char* str3
执行指针算法并访问所有150个字符。
答案 3 :(得分:0)
标签C和C ++是矛盾的。在C中,我建议探索realloc
。您可以按照以下方式编写代码:
char* str = malloc(50);
str = realloc(ptr, 55);
如果幸运的话,realloc
调用将不会重新分配新内存,只是“扩展”已分配的段,但不保证这一点。这样你至少可以避免重新分配字符串。您仍然需要将第二个字符串的内容复制到neweley分配的内存中。