使用realloc调整(减小)char数组的大小并检查是否成功

时间:2018-11-13 11:07:46

标签: c realloc

我尝试初始化动态char数组,如果用户输入的字符串较小,则该数组会减少。

问题是:我不知道,如果程序实际上正在执行此操作?我没有收到错误消息和正确的输出,但是未使用的内存真的释放了吗?

char *input=(char*)malloc(100);
gets(input);
int a = strlen(input);
input = realloc(input, a+1);

3 个答案:

答案 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;
}