【问题标题】:Why can't I reserve 1,000,000,000 in my vector?为什么我不能在我的向量中保留 1,000,000,000?
【发布时间】:2011-02-17 07:52:59
【问题描述】:

当我输入以下内容时。代码,我得到的输出为 1073741823。

#include <iostream>
#include <vector>
using namespace std;
int main()
{
  vector <int> v;
  cout<<v.max_size();
  return 0;
}

但是,当我尝试将向量的大小调整为 1,000,000,000 时,v.resize(1000000000); 程序停止执行。我怎样才能使程序能够分配所需的内存,而它似乎应该能够分配?

我在 Windows 7 中使用 MinGW。我有 2 GB RAM。不应该吗? 如果不可能,我不能将它声明为整数数组并逃脱吗?但即使这样也行不通。

另一件事是,假设我会使用一个文件(它可以轻松处理这么多数据)。 我怎样才能让它同时读取和写入。 首先,使用 fstream file("file.txt', ios::out | ios::in ); 不会创建文件。但是假设文件存在,我无法同时读写。 我的意思是: 设文件内容为111111 然后,如果我运行:-

#include <fstream>
#include <iostream>
using namespace std;
int main()
{
  fstream file("file.txt",ios:in|ios::out);
  char x;
  while( file>>x)
  {
    file<<'0';
  }
 return 0;
}

文件的内容现在不应该是 101010 吗?读取一个字符,然后用 0 覆盖下一个字符?或者如果整个内容被一次读入某个缓冲区,文件中是否应该至少有一个 0 ? 1111110 ? 但内容保持不变。请解释。 谢谢。

【问题讨论】:

  • 欢迎来到 Stack Overflow!这是两个不同的问题。一般来说,您应该单独询问他们。
  • 这是两个截然不同的问题。你能把它们分成两个问题帖子吗?
  • 谢谢。对不起,由于内存分配不起作用,我尝试做同样的事情,但是在一个文件中,并在那里得到了一组不同的错误。所以我把这些问题放在一起。下次我一定会单独问他们。
  • 如果您想解决这两个问题,我建议您将“另一件事”移至新线程。

标签: c++ file memory vector


【解决方案1】:
  1. 32 位进程一次只能寻址 4GB 地址空间。通常,这 4GB 地址空间中的大部分用于映射其他内容。您的向量将占用过多的连续地址空间(40 亿字节),这不太可能可用。

  2. 你应该memory map the file。见mmap

【讨论】:

  • 这个讨论:stackoverflow.com/questions/2791330/… 可能是密切相关的。
  • Win32 上的地址空间限制为 2GiB。我认为 Linux 应该是 3GiB。
  • @Vincent:Windows 上也有 3GB 开关,虽然默认是 2GB:technet.microsoft.com/en-us/library/bb124810%28EXCHG.65%29.aspx
  • 由于内存映射文件依赖于虚拟内存,地址范围限制依然存在。
  • @Clifford:您会注意到该示例一次处理一个字节。 IE。 vipersnake005 理解“内存不适合”的解决方案是“一次处理一个块”。他在将该原则应用于修改操作时遇到了问题。内存映射文件正好解决了这个问题:它们将文件的一部分映射到地址空间,并且对该地址空间的修改被写回文件。
【解决方案2】:

STL 实现可以处理的最大值是一回事;操作系统可用的最大内存量是另一回事;你打的是后者。

例如,您可能能够创建包含那么多 char 元素的向量。无论哪种方式,除非您物理上拥有那么多内存(加上操作系统和其他任何运行需要的东西),否则不要期望性能出众;毫无疑问,访问这样的向量会导致大量磁盘抖动,因为系统将内存分页进出磁盘。

此外,具有 32 位地址空间的处理器(或在运行 32 位操作系统时,无论物理地址空间如何)只能寻址 4Gb(物理或虚拟),因此存在架构限制。此外,一些操作系统限制了用户空间;例如,Win32 中的用户空间固定为 2Gb。各种版本的Win64人为地限制用户空间,以便让微软收取不同的价格,所以使用Win64并不能保证有足够的地址空间。

【讨论】:

    【解决方案3】:

    一个整数是四个字节,因此 1,000,000,000 个整数将占用大约 3.72GB。

    【讨论】:

    • 不,它需要(至少)正好 4 GB 或回旋处 3.72 GiB。详情请见binary prefix
    • @FredOverflow:有点迂腐!我见过的唯一经常使用的术语是在维基百科上。在这种情况下(读者可能不是计算机专家),它有助于消除歧义,但在这里我想我们都完全明白他的意思。
    【解决方案4】:

    您要求按连续顺序分配十亿个整数。除了很难找到如此巨大的连续空间之外,您根本就没有那个空间。回想一下,普通 32 位系统上的整数占用 32 位,即 4 个字节。将其乘以 10 亿,您将远远超出您拥有的 2GB。此外,std::vector 可以保留超出您要求的数量。

    关于第二个问题,如果您同时使用相同的fstream 对象进行读写,请确保在读写之前先seekg()seekp()

    【讨论】:

    • 有道理,它应该不能分配这么多。但那为什么v.maxsize() 允许我分配更多呢?
    • 关于 seekg 和 seekp,我的印象是,读写只有一个文件指针?如果有两个,我可以在不使用seekg(0)的情况下写入文件然后读取全部内容吗?
    • vector::max_size() 不会“允许”您分配那么多。它只告诉您标准库实现施加的限制是什么。你的硬件能否达到这个极限是另一回事。
    • 如果您写入文件然后希望使用相同的对象读取,那么您需要寻找您希望读取的位置。同样,如果您希望使用相同的对象写入您从读取的文件中,那么您必须寻找您希望写入的位置。写入和读取都会自动更改 get 和 put 指针,因此您必须自己调整它们。我个人觉得使用ifstream 对象读取文件和使用ofstream 写入文件更容易。
    【解决方案5】:

    但是,当我尝试通过 v.resize(1000000000) 将向量调整为 1,000,000,000 时;程序停止执行。如何启用 分配所需内存的程序,当它看起来 应该可以吗?

    它可能取决于 C++ STL 实现,但调整大小的行为通常会导致应用程序保留比您要求的更多的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-09
      • 2020-07-16
      • 1970-01-01
      • 1970-01-01
      • 2013-02-02
      • 1970-01-01
      • 2011-03-18
      • 1970-01-01
      相关资源
      最近更新 更多