【发布时间】:2022-01-22 23:31:51
【问题描述】:
remove_multiple 采用一个参数(一个 C 字符串),并删除重复项。它必须返回堆中动态分配的字符串。
我尝试过:
- 创建一个新的动态分配的指针;
- 如果(str)的当前字符不等于下一个字符,只需在重新分配 (s) 后将其复制到 s 中。
问题是我在 realloc 上仍然有这个警告:“C6308 'realloc' 可能返回空指针:将空指针分配给 's',它作为参数传递给 'realloc',将导致原始内存块被泄露”,当我尝试调试程序时收到一条消息,它说我试图在分配的内存之外写入。
这是我的代码:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
char* remove_duplicates(const char* str) {
char* s = malloc(sizeof(char));
if (!s) {
return NULL;
}
for (size_t i = 0; str[i] != 0; i++) {
if (str[i] != str[i + 1]) {
s = realloc(s, 2 * sizeof(char));
if (!s) {
return NULL;
}
s[i] = str[i];
}
}
return s;
}
int main(void) {
char str[] = "heyyyy";
char* s = remove_duplicates(str);
printf("%s", s);
free(s);
return 0;
}
错误列表:
- 警告 C6308 'realloc' 可能返回空指针:将空指针分配给作为参数传递给 'realloc' 的 's' 将导致原始内存块泄漏。
【问题讨论】:
-
警告非常具体。如果您获得返回值
NULL,您将无法再访问旧地址并且无法释放它,因为您已经用NULL值覆盖了变量。您可以改用temp变量,如果不是NULL,则仅分配给s。 -
realloc(s, 2 * sizeof(char));您将永远无法存储超过 2 个字符。这是故意的吗?我没有看到您将索引i限制为最大 1。 -
不,你为什么要分配
2?你写信给索引i。这意味着您必须至少分配i+1字节。 -
如果要删除重复字符,还必须使用 2 个索引变量。一个用于源数组,一个用于目标数组。
-
你需要
s = tmp,而不是*s = *tmp。对于少量分配,s = tmp通常是无操作的,因为它们已经相同,所以这个错误只会偶尔地咬你(在内存压力下)。但是您的代码中还有很多其他问题。
标签: c duplicates c-strings realloc function-definition