【问题标题】:C++ Reading File into Char ArrayC++ 将文件读入字符数组
【发布时间】:2012-11-08 09:18:44
【问题描述】:

我正在使用以下代码将文件读入字符数组。现在,对于小文件(比如 2 MB),它可以正常执行,但对于大文件(140 MB),在我的 18 GB UBUNTU 服务器中,它会给出segmentation fault。谁能帮我解决这个问题?我认为 18 GB 足以将 240 MB 文件保存到内存中。我正在使用 64 位 UBUNTU 并使用 g++ 进行编译。

ifstream is;

char chararray [fileSize] ;

is.read(chararray, fileSize) ;

【问题讨论】:

  • @milleniumbug:我认为fileSize 类似于size_t,其值为240*1024*1024...
  • @hmjd:嗯,他说没有。
  • 将第二行代码替换为char* chararray = new char[fileSize];
  • @Abbondanza 无需为此引入原始数组指针,这是一个 C 型解决方案。它们 (a) 容易泄漏并且 (b) 提供了忘记 delete[] 而不是 delete 的机会。向量更好……从 C++11 开始,您甚至可以从函数中返回大的向量,而无需支付复制它的成本,这要归功于 return value optimization 期间发生的复制省略。
  • @Abbondanza ...不要忘记异常安全!向量——作为一个带有析构函数的类——可以自行清理。原始指针只会泄漏! :-/

标签: c++ linux gcc ubuntu


【解决方案1】:

我尝试使用std::vector,而不是在堆栈上分配char数组,它将在上动态分配:

std::vector<char> buffer(fileSize);
is.read(&buffer[0], fileSize);

【讨论】:

    【解决方案2】:

    如果数组是一个局部变量,你会得到一个堆栈溢出,因为它不适合堆栈。而是在堆上分配“数组”,直接使用new 或间接使用std::vector

    或者使用内存映射。请参阅mmap 函数。

    【讨论】:

    • std::vector 可能更可取,但由于他说这是一个 Unix 变体,ulimit -s 500000,在他运行他的程序之前调用,应该可以工作。
    • ulimit 从命令行运行是一种不可移植地解决问题的丑陋方式,在这种情况下,可以在代码本身中轻松管理。
    • @Richard 正如我所说,使用std::vector 可能更可取。但是知道ulimit也没有错。
    • @peterph 是的,内存映射是一件好事……尽管如果使用 C++ 编程,那么使用封装在类中的东西 platform-independent 比 POSIX mmap 更可取。只是如果一个问题被标记为 C++,那么我认为需要反对建议调用 new[] (当然还有 malloc ...)的方法
    • @HostileFork 如果您使用 C++ 编程,您将在类中包装 mmap,在析构函数中使用 munmap。并且可能给类一个尽可能接近std::vectorstd::array 的接口,让用户对它有宾至如归的感觉。然而,由于所涉及的工作,我只会读到std::vector,直到我知道我需要性能(但如果我需要它一次,我会将这个类保留在我的工具包中,然后立即使用它) .
    【解决方案3】:

    GCC 编译器为此提供了名为 size 的默认命令!使用 GCC 编译器编译程序。然后就可以得到文件大小了!

    gcc -Wall test.c
    size
    

    这是一个普通的 C 程序!由于您未指定任何参数,因此它将 ./a.out 作为其默认参数!

    如果你必须应用一些优化,代码将变成如下..

    praveenvinny@ubuntu:~/Project/New$> gcc -Wall -o1 -fauto-inc-dec test.c -o Output
    praveenvinny@ubuntu:~/Project/New$> size output
    text       data     bss     dec     hex filename
    1067       256      8       1331    533 output
    

    使用文本部分来确定代码大小。 如果您还想考虑全局数据大小,可以使用 data 和 bss。

    这将打印代码大小,

    time -f "%e" -o Output.log ./a.out
    

    将执行时间打印到名为 Output.log 的日志文件中

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-08
      • 1970-01-01
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多