【问题标题】:Reading file into 2d char array works for 500 lines but not 50,000将文件读入二维字符数组适用于 500 行但不是 50,000
【发布时间】:2019-09-14 11:27:40
【问题描述】:

我要做的就是将文件的行读入二维字符数组。我计算了最长行中的行数和字符数(使用函数lineCount())。在我的第一种情况下,它是 500 行,最多 50 个字符。第二种情况是 50,000 行,最多 30 个字符。这是我的main()

int main(int argc, char** argv)
{
    char fileName[] = "C:\\valid_50K.txt";

    int p[2] = { 0, 0 };
    lineCount(&fileName, &p);

    uint8_t** lines = (uint8_t**)malloc(sizeof(uint8_t*) * p[0]);
    for (int lnVar = 0; lnVar < p[0]; lnVar++)
    {
        lines[lnVar] = (uint8_t*)malloc(p[1] + 1);
    }

    readLines(&fileName, p[1], lines);   
}

这里是readLines():

void readLines(char* fileName, int numChars, uint8_t** out)
{
    FILE *fptr = NULL;
    int i = 0;

    fptr = fopen(fileName, "r");

    while (fgets(out[i], numChars + 1, fptr))
    {
        out[i][strlen(out[i]) - 1] = '\0';
        i++;
    }

    fclose(fptr);
}

它适用于 500 行,但对于 50K,我在 out[i][strlen(out[i]) - 1] = '\0'; 行上收到错误 Unhandled exception at 0x00007FFAAD21BC78 (ucrtbase.dll) in test.exe: An invalid parameter was passed to a function that considers invalid parameters fatal。整个文件只有1MB,只有ASCII字符,不明白是什么问题。我正在使用 Visual Studio 2017。

【问题讨论】:

  • minimal reproducible example 请。那还不是一个可编译的程序
  • 每当我看到一个数组的地址操作符时(如&amp;fileName 中的&amp;p),我都认为这是一个危险信号。 &amp;fileName 的类型是 char (*)[18],而不是 char *
  • 当然你还需要检查malloc的返回值。它是否成功分配了这么多内存?
  • lineCount(&amp;fileName, &amp;p); 可能也有弱点。发布minimal reproducible example
  • 一定要告诉我们lineCount 。并且总是检查malloc的返回值。 (这只是一个铁定的规则。即使您分配 1 个字节并且它“不可能失败”。即使在您将运行一次并丢弃的测试程序中。总是 检查malloc 的返回值。)

标签: c file multidimensional-array


【解决方案1】:

整个文件只有1MB,
它适用于 500 行,但对于 50K ...

考虑一个包含 49,999 行 '\n' 和 1 行 (1MB-49,999) 长度的文件将在 p[] 中返回 { 50000, about 1MB }。然后代码将尝试分配50000 * about 1MB 字节或大约50 GB。

查看malloc()的返回是否为NULL


如果一行中读取的第一个字符是空字符,则

out[i][strlen(out[i]) - 1] = '\0'; 是未定义的行为。

如果一行不包含结尾 '\n',这在功能上是有问题的。

建议:

out[i][strcspn(out[i], "\n")] = '\0';

【讨论】:

    猜你喜欢
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 2014-04-06
    相关资源
    最近更新 更多