我尝试初始化动态char
数组,如果用户输入的字符串较小,则该数组会减少。
问题是:我不知道,如果程序实际上正在执行此操作?我没有收到错误消息和正确的输出,但是未使用的内存真的释放了吗?
char *input=(char*)malloc(100);
gets(input);
int a = strlen(input);
input = realloc(input, a+1);
答案 0 :(得分:3)
不要在C中强制转换*alloc()
的结果。不需要它,只会使代码混乱,在最坏的情况下,它会掩盖错误,例如为#inlude <stdlib.h>
忘记*alloc()
行
input = realloc(input, a+1);
是有问题的,因为如果realloc()
失败并返回NULL
,则会丢失先前的指针值。更好:
char *new_input = realloc(input, a+1);
if(!new_input) {
free(input);
// print some error message
return EXIT_FAILURE;
}
// everything fine:
input = new_input;
// use input
free(input);
PS:此外,正如其他人在评论中指出的那样:从词汇表中删除gets()
。假装它根本不存在。请改用fgets()
。
答案 1 :(得分:1)
通常,检查分配器功能是否成功的唯一方法是通过对realloc()
指针的NULL
调用来检查返回的指针。如果返回的指针不是NULL
,则可以确保调用成功。
下面是类似的方法
pointer = realloc (pointer, newValue);
是有问题的,例如在realloc()
失败的情况下,引自C11
,第7.22.3.5章,
[....]如果无法为新对象存储 分配后,旧对象不会被释放,其值保持不变。
和
realloc
函数返回一个指向新对象的指针(该对象可能具有相同的指针 值作为指向旧对象的指针),如果新对象不能为null,则返回null指针 已分配。
因此,返回的空指针将覆盖先前的 valid 内存地址,您将失去访问权限并泄漏内存。安全的做法是
type tempPOinter = NULL;
tempPOinter = realloc(oldPointer, newSize);
if (tempPOinter) {
oldPointer = tempPOinter;
}
else {
printf("Failure in realloc!!");
free(oldPointer);
return -1;
}
答案 2 :(得分:0)
我建议您更改算法。 在C语言中,您可以在堆栈上保留一个足够大的缓冲区,然后在读取输入后在堆上分配一个永久缓冲区:
#define BIG_ENOUGH 4096
char *get_line(FILE *fp)
{
char buf[BIG_ENOUGH] = "";
return fgets(buf, BIG_ENOUGH - 1, fp) ? strdup(buf) : NULL;
}