我正在寻找一种附加多个字符串的有效方法 它的工作方式是C ++ std :: string :: append或JAVA StringBuffer.append。
我编写了一个实际重新分配前一个源指针并执行strcat的函数。
我认为这不是一种有效的方法,因为编译器可以实现这个free和malloc。
我能想到的其他方式(如std :: vector)是批量分配内存(例如1KB)并执行strcpy。在这种情况下,每个追加调用将检查所需的总分配是否大于(1200字节)批量分配的数量,重新分配到2KB。但在这种情况下会浪费一些内存。
我正在寻找上述之间的平衡,但偏好是表现。
还有哪些方法可行。请建议。
答案 0 :(得分:4)
我会将每个字符串添加到列表中,并将每个新字符串的长度添加到运行总计中。然后,当你完成后,为该总数分配空间,遍历列表并将每个字符串strcpy到新分配的空间。
答案 1 :(得分:2)
经典方法是每次缓冲时将缓冲区加倍。
从一个“合理的”缓冲区开始,所以你不需要对大小为1,2,4,8,1的realloc()
进行操作,这些大小会被大量的字符串击中
从1024字节开始意味着如果你点击2048就会有一个realloc()
,如果你达到4096就会有一秒{2},依此类推。如果猖獗的内存消耗让你感到害怕,那么一旦达到适当大的增长率(如65536字节或其他),就会限制增长率,这取决于你的数据和内存容忍度。
另外请确保缓冲当前长度,这样您就可以strcpy()
执行{{1}}而无需先走动字符串来查找长度。
答案 2 :(得分:0)
连接字符串的示例函数
void
addToBuffer(char **content, char *buf) {
int textlen, oldtextlen;
textlen = strlen(buf);
if (*content == NULL)
oldtextlen = 0;
else
oldtextlen = strlen(*content);
*content = (char *) realloc( (void *) *content, (sizeof(char)) * (oldtextlen+textlen+1));
if ( oldtextlen != 0 ) {
strncpy(*content + oldtextlen, buf, textlen + 1);
} else {
strncpy(*content, buf, textlen + 1);
}
}
int main(void) {
char *content = NULL;
addToBuffer(&content, "test");
addToBuffer(&content, "test1");
}
答案 3 :(得分:0)
我会做这样的事情:
typedef struct Stringbuffer {
int capacity; /* Maximum capacity. */
int length; /* Current length (excluding null terminator). */
char* characters; /* Pointer to characters. */
} Stringbuffer;
BOOL StringBuffer_init(Stringbuffer* buffer) {
buffer->capacity = 0;
buffer->length = 0;
buffer->characters = NULL;
}
void StringBuffer_del(Stringbuffer* buffer) {
if (!buffer)
return;
free(buffer->characters);
buffer->capacity = 0;
buffer->length = 0;
buffer->characters = NULL;
}
BOOL StringBuffer_add(Stringbuffer* buffer, char* string) {
int len;
int new_length;
if (!buffer)
return FALSE;
len = string ? strlen(string) : 0;
if (len == 0)
return TRUE;
new_length = buffer->length + len;
if (new_length >= new_capacity) {
int new_capacity;
new_capacity = buffer->capacity;
if (new_capacity == 0)
new_capacity = 16;
while (new_length >= new_capacity)
new_capacity *= 2;
new_characters = (char*)realloc(buffer->characters, new_capacity);
if (!new_characters)
return FALSE;
buffer->capacity = new_capacity;
buffer->characters = new_characters;
}
memmove(buffer->characters + buffer->length, string, len);
buffer->length = new_length;
buffer->characters[buffer->length] = '\0';
return TRUE;
}