以下是考试引述(1% 顶尖大学)。
我失败了,因为我的答案与“批准”的答案不同。
我有一种预感,他的(教授,著名的 C 专家)答案是不正确的。
以下是“批准”答案后的问题。
There is a potential bug in the following function. What is it and how would I fix it?
Hint: this has something to do with the use of the realloc() function. Please identify the line numbers you would change and what you would replace them with.
BOOLEAN lengthen_string(char* string, const char newcontents[]) { int newlen = strlen(string) + strlen(newcontents) + 1; string = realloc(string, newlen); if (!string) { perror("malloc"); return FALSE; } strcat(string, newcontents); return TRUE; }
教授提供的“正确”答案是:
line 4: realloc returns a NULL pointer when it fails to allocate. This means that on failure the original data is lost.
To fix this, assign the result of realloc to a temporary variable and test that first.
Ie: line 4:
char * temp=realloc(string, newlen); if(!temp) ... (all remains the same)
after old line 9,
string = temp
;
有什么想法吗?
顺便说一句,我的回答是@string是一个局部变量,函数的原型(prototype)应该是char **string
,这里调用者传递一个指向它的字符串指针,然后被调用者会将任何 realloc() 返回值分配给 *string
有什么想法吗?
最佳答案
你们都是对的。
教授是正确的,因为 realloc()
不会在失败时改变传入的内存,从而使输入的 string
指针完好无损,但是如果 NULL失败的返回值立即分配给 string
然后原始数据丢失和泄漏。因此,在将新指针值分配给 string
之前,需要首先检查是否存在故障。
你是对的,因为 string
需要通过指针传递,因此如果 realloc()
返回不同的内存地址,它可以重新分配一个新值。
正确的解决方案应该是这样的:
BOOLEAN lengthen_string(char** string, const char newcontents[])
{
if (!string)
{
errno = EINVAL;
perror("bad input");
return FALSE;
}
size_t newsize = strlen(*string) + strlen(newcontents) + 1;
char *temp = realloc(*string, newsize);
if (!temp)
{
perror("realloc failed");
return FALSE;
}
strcat(temp, newcontents);
*string = temp;
return TRUE;
}
或者,还有一些优化空间,eg:
BOOLEAN lengthen_string(char** string, const char newcontents[])
{
if (!string)
{
errno = EINVAL;
perror("bad input");
return FALSE;
}
char *temp;
if (!*string)
{
temp = strdup(newcontents);
if (!temp)
{
perror("strdup failed");
return FALSE;
}
}
else
{
size_t offset = strlen(*string);
size_t size = strlen(newcontents) + 1;
temp = realloc(*string, offset + size);
if (!temp)
{
perror("realloc failed");
return FALSE;
}
memcpy(temp + offset, newcontents, size);
}
*string = temp;
return TRUE;
}
关于c - 如果 Realloc() 失败,调用者是否会丢失前一个 malloc() 调用中的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61967608/