【问题标题】:Reading and writing Large files in C用 C 读写大文件
【发布时间】:2013-04-13 22:23:23
【问题描述】:

我想知道以下代码中的问题。这用于首先打开一个大小为 800Mb 的文件以填充 name 变量,然后用于通过从另一个文件读取索引来访问存储在其中的数据。问题是,在读取并填充数组名称后,从它访问任何元素都会出现段错误。当在较小的数据量上测试相同的代码时,它可以工作。可能是什么原因?我运行它的硬件是 4gb RAM,intel i5 芯片上的 32 位 linux 版本。

#include <stdio.h>
#define MAXINT 61578414
int main(int argc,char** argv){
    printf("Starting \n");    

    FILE* fp1 = fopen(argv[1],"r");
    FILE* fp2 = fopen(argv[2],"r");


    char** name;
    name = (char**)malloc(MAXINT*sizeof(char*));

    char* tname;

    int i = 0;
    int tmp1;


    //reading to fill in name
    while(i < MAXINT){
        name[i] = (char*)malloc(20);
        fscanf(fp1,"%d%s",&tmp1,name[i]);
        i++;
    }

    //accessing elements from  name
    int i1,i2;
    while(!feof(fp2)){
        fscanf(fp2,"%d%d",&i1,&i2);
        fprintf(stdout,"%s %s\n",*(name+i1),*(name+i2));
    }

}

【问题讨论】:

  • 1) 包括 2) 不要转换 malloc() 的返回值。 3) feof() 总是错误的。 4) name[i1]*(name+i1) 更容易阅读 5) (minor) main() 应该返回一个 int 值,在大多数情况下为零。
  • 查看malloc的返回值。
  • 我也没有看到分配的内存在任何地方被释放?
  • 是的,将合并更改,但问题是 name[i1] 我遇到了分段错误。
  • @MartinWickman 不需要上述条件。i1i2 应在(0, MAXINT - 1) 范围内

标签: c io


【解决方案1】:

name 的分配存在一个潜在问题。

char** name;
name = (char**)malloc(MAXINT*sizeof(char*));

name 被定义为一个指向指针的指针,它是一个指针数组。代码分配了MAXINT的指针数量,这是一个非常大的数字。您需要检查next 是否已成功分配或NULL 指针是否已删除,即malloc 是否成功。

同样,name[i] = malloc(20) 也应检查 NULL 指针,因为您的系统可能会耗尽内存。

【讨论】:

  • 是的,将合并更改,但是当我检查时,它能够在每个malloc调用时分配那么多空间@
  • @ImWatchingYou 如果要打印字符串,这个语句fprintf(stdout,"%s %s\n",*(name+i1),*(name+i2))不能改成fprintf(stdout,"%s %s\n", name[i1],name[i2])。您选择代码的任何原因?
  • 当我尝试name[i1] 时抛出了分段错误。我教过*(name+ i1 ) 可能有助于避免它。但后来意识到两者是相同的
  • @ImWatchingYou.. 你检查过i1i2 的值吗?你能确认这在所有情况下都在(0, MAXINT - 1) 的范围内吗?另外,您能否粘贴输入和索引文件的示例以进一步了解问题?
  • "MAXINT 指针数量,这是一个非常大的数字" -- MAXINT != MAX_INT;前者是在程序中定义的,并没有那么大。
【解决方案2】:

这是在 Linux 上吗?在这种情况下,(默认情况下)来自 malloc 的非 NULL 值不会告诉您是否真的可以访问您请求的内存量。实际上,这意味着您可以分配比可用内存多得多的内存。只有当您真正访问它时,才会分配它的内存。

所以编写一个简单的循环,它只读取或写入您 malloc'ed 的每个字节,看看是否崩溃。如果是这样,那就是你的问题了。

附带说明一下,您是否考虑过使用mmap() 来处理大文件/内存分配?

【讨论】:

    【解决方案3】:

    我想name = (char**)malloc(MAXINT*sizeof(char*)); 实际上失败了,你应该在那里检查 NULL 返回值。

    【讨论】:

      猜你喜欢
      • 2012-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多