令人惊讶的简单/愚蠢/基本问题,但我不知道:假设我想给函数的用户返回一个C字符串,在函数开头我不知道它的长度.我只能在一开始就给长度设定一个上限,而且,根据处理的不同,大小可能会缩小.
问题是,在处理过程中分配足够的堆空间(上限),然后在远远低于上限的范围内终止字符串,这有什么不对吗?即,如果我在分配的内存中间插入‘\0’,(a.)free()
是否仍然正常工作,以及(b.)‘\0’之后的空格是否变得无关紧要?一旦添加了‘\0’,内存是直接返回,还是一直坐在那里占用空间直到调用free()
?为了节省一些前期编程时间,在调用malloc之前计算必要的空间,将这个挂起空间留在那里通常是不好的编程风格吗?
为了给它一些上下文,假设我想删除连续的重复项,如下所示:
input "Hello oOOOo !!" --> output "Helo oOo !"
... 下面的一些代码显示了我如何预计算操作产生的大小,有效地执行两次处理以获得正确的堆大小.
char* RemoveChains(const char* str)
{
if (str == NULL) {
return NULL;
}
if (strlen(str) == 0) {
char* outstr = (char*)malloc(1);
*outstr = '\0';
return outstr;
}
const char* original = str; // for reuse
char prev = *str++; // [prev][str][str+1]...
unsigned int outlen = 1; // first char auto-counted
// Determine length necessary by mimicking processing
while (*str) {
if (*str != prev) { // new char encountered
++outlen;
prev = *str; // restart chain
}
++str; // step pointer along input
}
// Declare new string to be perfect size
char* outstr = (char*)malloc(outlen + 1);
outstr[outlen] = '\0';
outstr[0] = original[0];
outlen = 1;
// Construct output
prev = *original++;
while (*original) {
if (*original != prev) {
outstr[outlen++] = *original;
prev = *original;
}
++original;
}
return outstr;
}