p b*_*inb 3 c memory malloc glibc realloc
以下是考试的引述(1% 的顶尖大学)。
我失败了,因为我的答案与“批准”的答案不同。
我有一种预感,他(教授,著名的 C 专家)的答案是不正确的。
以下是问题后跟“批准”的答案。
以下功能存在潜在错误。它是什么,我将如何修复它?
提示:这与 realloc() 函数的使用有关。请确定您将更改的行号以及您将用什么来替换它们。
Run Code Online (Sandbox Code Playgroud)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; }
教授提供的“正确”答案是:
第 4 行: realloc 在分配失败时返回 NULL 指针。这意味着一旦失败,原始数据就会丢失。
要解决此问题,请将 realloc 的结果分配给临时变量并首先对其进行测试。
即:第4行:
Run Code Online (Sandbox Code Playgroud)char * temp=realloc(string, newlen); if(!temp) ... (all remains the same)在旧的第 9 行之后,
string = temp;
有什么想法吗?
顺便说一句,我的回答是 @string 是一个局部变量,函数的原型应该是 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;
}
Run Code Online (Sandbox Code Playgroud)
或者,还有一些优化空间,例如:
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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
103 次 |
| 最近记录: |