刚从一些手册文档中完成了这个函数的组合,它会使用一个char*并附加一个const char*,如果char*的大小太小,它会将其重新分配给稍大的值,最后再附加它。我使用c已经很久了,所以只需签入即可。
// append with realloc
int append(char *orig_str, const char *append_str) {
int result = 0; // fail by default
// is there enough space to append our data?
int req_space = strlen(orig_str) + strlen(append_str);
if (req_space > strlen(orig_str)) {
// just reallocate enough + 4096
int new_size = req_space;
char *new_str = realloc(orig_str, req_space * sizeof(char));
// resize success..
if(new_str != NULL) {
orig_str = new_str;
result = 1; // success
} else {
// the resize failed..
fprintf(stderr, "Couldn't reallocate memoryn");
}
} else {
result = 1;
}
// finally, append the data
if (result) {
strncat(orig_str, append_str, strlen(append_str));
}
// return 0 if Ok
return result;
}
这是不可用的,因为您从未告诉调用者从realloc
返回的内存在哪里。
您需要返回一个指针,或者通过引用传递orig_str
。
此外(如注释中所指出的),您需要执行realloc(orig_str, req_space + 1);
,以便为null终止符留出空间。
与这个固定版本相比,你的代码有一些低效的逻辑:
bool append(char **p_orig_str, const char *append_str)
{
// no action required if appending an empty string
if ( append_str[0] == 0 )
return true;
size_t orig_len = strlen(*p_orig_str);
size_t req_space = orig_len + strlen(append_str) + 1;
char *new_str = realloc(*p_orig_str, req_space);
// resize success..
if(new_str == NULL)
{
fprintf(stderr, "Couldn't reallocate memoryn");
return false;
}
*p_orig_str = new_str;
strcpy(new_str + orig_len, append_str);
return true;
}
这个逻辑没有任何意义:
// is there enough space to append our data?
int req_space = strlen(orig_str) + strlen(append_str);
if (req_space > strlen(orig_str)) {
只要append_str
的长度为非零,就必须重新分配。
主要的问题是,您试图用strlen
跟踪缓冲区的大小。如果您的字符串以NUL结尾(应该是这样),那么您感知到的缓冲区大小将始终是其中数据的确切长度,忽略任何额外的长度。
如果你想使用这样的缓冲区,你需要在一个单独的size_t
中跟踪大小,或者保留一些像这样的描述符:
struct buffer {
void *buf;
size_t alloc_size;
size_t used_amt; /* Omit if strings are NUL-terminated */
}