DWORD convert(char *point, DWORD extent)
{
char *point_end = point + extent;
char *result = memory_alloc(1);
char *p_result = result;
while (point < point_end)
{
switch (*point)
{
case FOO:
result_extent = p_result - result;
result = memory_realloc(12);
result += result_extent;
*p_result++ = '\n';
*p_result++ = '\t';
memcpy(result, point, 10);
point += 10;
result += 10;
break;
case BAR:
result_extent = p_result - result;
result = memory_realloc(1);
result += result_extent;
*result++ = *point++;
break;
default:
point++;
break;
}
}
// assume point is big enough to take anything I would copy to it
memcpy(point, result, result_extent);
return result_extent;
}
memory_alloc()和memory_realloc()都是虚假函数,用于强调我的问题的目的。我事先不知道结果“string”的大小(技术上讲,我正在处理的不是一个C样式/空终止字符串,而只是指向内存地址和长度/范围的指针),因此我需要动态调整结果字符串的大小(它可能比输入大,也可能比输入小)。
在我的第一次尝试中,我使用malloc()创建了第一个字节/字节的空间,然后每当需要附加另一个字节/几个字节时就会重新分配(realloc())...这样做也可以,但感觉这种方法将不必要地消耗操作系统资源,并且可能会导致反复移动内存中的字节。
所以我进行了第二次尝试,该尝试确定了经过单个转换单位(如FOO和BAR)后结果字符串的长度,并选择“首选分配大小”,例如256字节。例如,如果result_extent为250个字节,并且我处于FOO情况下,我知道我需要增加12个字节的内存(换行符、制表符和10个来自输入字符串的字节)——而不是重新分配260个字节的内存,我会寻找512个字节,押注自己可能会继续添加更多数据(因此我可以避免对realloc的调用)。
那么我的问题是:这种想法是否正确,或者说这是编译器/操作系统可能已经替我处理好的过早的优化?除了不浪费内存空间外,将内存按几个字节重新分配,还有其他优点吗?
我对单个转换实例可能会遇到的情况有一些粗略的想法,例如,最坏的情况可能是一个大小为2MB的输入字符串,其中包含几百个字节的标记,并且每个标记实例会增加50-100个字节的数据到结果字符串中(因此需要大约200次realloc来将字符串扩展50-100个字节,并且另外还要进行大约100次realloc,仅从输入字符串复制数据到结果字符串中,不涉及标记)。
如果您有关于这个话题的想法,请让我知道。谢谢!