使用动态内存分配设置char数组的确切大小

时间:2014-11-28 20:43:00

标签: c arrays memory dynamic char

我必须从stdin读取一些字符(我不知道它们中有多少,但不超过MAX)并且我想将它们存储在一个数组中。这段代码片段是否正确?

char *c1 = (char*) malloc(MAX * sizeof(char)); //may be too much
fgets(c, MAX, stdin);
int size = strlen(c1);
char *c2 = (char*) realloc(c1, size * sizeof(char));
free(c1);

或者,当您不知道要存储多少元素时,是否有一种更优雅的方法来确定为阵列分配的内存量?

1 个答案:

答案 0 :(得分:1)

fgets()中,您可能需要c1,而不是c

你可以这样做(如果你坚持使用realloc()):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAX 50

int main() {
  char *c1 = malloc(MAX * sizeof(char));
  if(!c1) {
    printf("malloc() failed\n");
    return -1;
  }
  fgets(c1, MAX, stdin);
  int size = strlen(c1);
  char* c2;
  if(c1[size - 1] == '\n') {
    c1[size - 1] = '\0';
    c2 = realloc(c1, (size) * sizeof(char));
  } else {
    c2 = realloc(c1, (size + 1) * sizeof(char));
  }
  if(!c2) {
    printf("realloc() failed\n");
    return -1;
  }
  c1 = NULL;
  printf("Input was: %s\n", c2);
  free(c2);
  return 0;
}

以下是一些评论:

  1. 您希望读取字符串,因此您应该使用char*,而不是。{ int*

  2. 通常,您不希望保留fgets()读取的换行符, 因此我用了c1[size - 1] = '\0';来覆盖它。但是,如果用户输入了允许的最大字符数,那么就没有空间,因此我们会检查换行符是否真的存储在缓冲区中。

  3. Do not cast what malloc() returns.

  4. realloc()中,您应该为大小分配空间 字符串,加上空终止者。这就是现在size+1的原因。但是,在我们覆盖换行符的情况下,没有必要这样做,因为我们已经将字符串的大小减小了一个,因此size就足够了。

  5. 永远不要忘记取消分配你的记忆。


  6. 但是,如果我是你,我会打印一条消息,警告用户输入MAX字符并避免重新分配。

    您会看到,ref of fgets()状态,函数将:

      

    从流中读取字符并将它们作为C字符串存储到str中,直到读取(num-1)个字符或者到达换行符或文件结尾为止,以先发生者为准。

    因此,即使用户输入更多,程序也不会崩溃。


    正如Paul正确评论的那样,使用第二个指针是个好主意,这样如果realloc()失败,我们就不会丢失数据。

    另请注意,您不应该释放c1,因为此指针无效且应设置为NULLc1可能指向c2点的位置,因此如果我们释放c1,则c2将指向垃圾。或者可能是整个内存块被转移到其他地方,因此c1指向垃圾,我们试图释放。