gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 03:42:50 25 4
gpt4 key购买 nike

我必须从 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);

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

最佳答案

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()中,你应该为字符串,PLUS THE NULL TERMINATOR。这就是为什么它现在是 size+1。然而,在我们覆盖换行符的情况下,没有必要这样做,因为我们已经将字符串的大小减少了一个,因此 size 就足够了。

  5. 永远不要忘记释放内存。


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

你看,作为ref of fgets()声明,该函数将:

Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.

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


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

另请注意,您不应释放 c1,因为此指针已失效且应设置为 NULLc1 可能指向 c2 指向的位置,因此如果我们释放 c1,那么 c2 将指向垃圾。或者可能是整个内存块都转移到了其他地方,因此 c1 指向垃圾,我们正在尝试释放。

关于c - 使用动态内存分配设置 char 数组的确切大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27195638/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com