gpt4 book ai didi

c - 从文件管道输入时,realloc 无法扩展 char 数组

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

我编写了下面的 c 函数来从用户那里获取一个字符串。它使用 realloc 动态更改 char 数组大小以适应未知的 char 数组长度。据我了解,它应该能够接受尽可能多的输入(或有可用内存),但是,当我尝试从随机文本文件(使用“tr '\n' ' ' ./random.txt”以确保我从文本文件中删除了所有换行符),我得到“无法分配内存来保存 char 数组。退出!”错误信息。为什么会这样?我的阵列是否应该能够容纳多达 GB 的数据,因为我有 16 GB 的 RAM,其设计方式是动态增长的?

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

void GetString(int*, int*);

int main(void)
{
unsigned int strLength = 32;
char *stringPtr = malloc(strLength);
if (stringPtr == NULL)
{
fprintf(stderr, "Unable to allocate memory to hold char array. Exiting!\n");
return 1;
}
printf("Enter some input: ");
int c = EOF;
unsigned int i = 0;
while ((c = getchar()) != '\n' && c != EOF)
{
stringPtr[i++] = (char) c;
if (i == strLength)
{
strLength *= strLength;
if ((stringPtr = realloc(stringPtr, strLength)) == NULL)
{
fprintf(stderr, "Unable to expand memory to hold char array. Exiting!\n");
return 2;
}
}
}
stringPtr[i] = '\0';
if (sizeof(stringPtr) < strLength)
{
stringPtr = realloc(stringPtr, i);
}
printf("\n\nString value: %s\n\n\n", stringPtr);
free(stringPtr);
stringPtr = NULL;
}

最佳答案

我稍微修改了你的程序以帮助找出问题所在:

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

int main(void)
{
unsigned int strLength = 32;
char *stringPtr = malloc(strLength);
if (!stringPtr)
{
fprintf(stderr, "failed to allocate %u bytes: %s\n",
strLength, strerror(errno));
return 1;
}
int c = EOF;
unsigned int i = 0;
while ((c = getchar()) != '\n' && c != EOF)
{
stringPtr[i++] = (char) c;
if (i == strLength)
{
unsigned int nStrLength = strLength;
nStrLength *= nStrLength;
if (nStrLength <= strLength)
{
fprintf(stderr, "cannot grow string of %u bytes any more\n",
strLength);
return 1;
}
if ((stringPtr = realloc(stringPtr, nStrLength)) == NULL)
{
fprintf(stderr,
"failed to enlarge string from %u to %u bytes: %s\n",
strLength, nStrLength, strerror(errno));
return 1;
}
strLength = nStrLength;
}
}
return 0;
}

当或多或少像你那样运行时,这就是我得到的:

$ yes | tr -d '\n' | ./a.out 
cannot grow string of 1048576 bytes any more

1048576 是 1 兆字节,但更重要的是,它是 220。 220 的平方是 240,大于 232 - 1,这是一个可以表示的最大值unsigned int 在这个系统上。我预计您会在您的系统上获得相同的结果。

因此,我建议您进行三处更改:

  • 正如我已经提到的,所有这些 unsigned int 变量都应该是 size_t
  • 正如 chux 已经提到的,将您的代码更改为仅将 strLength 乘以 2 而不是乘以它本身。
  • 按照我在此处所做的工作对溢出进行显式检查。 或者采用reallocarray ,它可能不在您的 C 库中,但您可以从链接中加入。 [编辑: reallocarray 通常仍然是个好主意,但是它对这类数字溢出错误没有帮助,因为溢出的是数组中的项数,而不是项数和大小的乘积。]

此外,这次不是您的直接问题,但为了将来引用,strerror(errno) 是您的 friend 。当系统原语失败时总是打印 strerror(errno)

关于c - 从文件管道输入时,realloc 无法扩展 char 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26351328/

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