令人惊讶的简单/愚蠢/基本问题,但我不知道:假设我想向函数的用户返回一个 C 字符串,在函数的开头我不知道它的长度。最初只能对长度设置上限,根据加工,有尺寸缩小的情况。
问题是,分配足够的堆空间(上限)然后在处理期间终止字符串是否有任何问题?即如果我将'\0' 粘贴到分配的内存的中间,(a.)free()
是否仍然正常工作,并且(b.)'\0' 之后的空间是否变得无关紧要?添加 '\0' 后,内存是否会被返回,还是会一直占用空间直到free()
被调用?为了节省一些前期编程时间,在调用 malloc 之前计算必要的空间,将这个悬挂空间留在那里通常是不好的编程风格吗?
为了给出一些上下文,假设我想删除连续的重复项,如下所示:
输入“你好哦哦哦!!” --> 输出“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;
}