【问题标题】:Can't deque.push_back() 10 million+ deques不能 deque.push_back() 1000 万+双端队列
【发布时间】:2014-05-14 02:16:46
【问题描述】:

我是一名学生,我的操作系统课程项目有一点小问题,这对于作业规范本身来说确实有点多余:

虽然我可以将 100 万双端队列推送到我的双端队列中,但我无法推送大约 1000 万或更多。

现在,在实际程序中,发生了很多事情,而在 Stack Overflow 上已经询问过的唯一一个即使是最轻微的相关性也正是如此,只有轻微的相关性。 https://stackoverflow.com/a/11308962/3407808

由于该答案集中在“破坏堆的其他函数”,我将代码隔离到一个新项目中并单独运行,发现一切都以完全相同的方式失败。

这是代码本身,为节省空间而被剥离并重命名。

#include <iostream>
#include <string>
#include <sstream>
#include <deque>

using namespace std;

class cat

{
    cat();
};

bool number_range(int lower, int upper, double value)
{
    while(true)
    {
        if(value >= lower && value <= upper)
        {
            return true;
        }
        else
        {
            cin.clear();
            cerr << "Value not between " << lower << " and " << upper << ".\n";
            return false;
        }
    }
}

double get_double(char *message, int lower, int upper)
{

    double out;
    string in;

    while(true) {

        cout << message << " ";
        getline(cin,in);
        stringstream ss(in); //convert input to stream for conversion to double

        if(ss >> out && !(ss >> in))
        {
            if (number_range(lower, upper, out))
            {
                return out;
            }
        }
        //(ss >> out) checks for valid conversion to double
        //!(ss >> in) checks for unconverted input and rejects it

        cin.clear();
        cerr << "Value not between " << lower << " and " << upper << ".\n";
    }
}

int main()
{
    int dq_amount = 0;
    deque<deque <cat> > dq_array;
    deque<cat> dq;

    do {
        dq_amount = get_double("INPUT # OF DEQUES: ", 0, 99999999);
        for (int i = 0; i < number_of_printers; i++)
        {
            dq_array.push_back(dq);
        }
    } while (!number_range(0, 99999999, dq_amount));
}

如果这有点混淆,设计(以防它与错误有关)是我的程序要求您输入一个整数值。它接受您的输入并验证它是否可以被读取为整数,然后进一步解析它以确保它在一定的数值​​范围内。一旦在范围内找到它,我将 myClass 的 deques 推送到 myClass 的 deques 的 deque 中,次数等于用户输入的次数。

在我制作这个项目的过去几周里,这段代码一直在工作,但我的上限一直是 9999,我决定用我的程序中的大多数其他输入来标准化它,这是一个相当大的 99,999,999。尝试使用 9999 作为用户输入运行此代码可以正常工作,即使将 99999999 作为上限也是如此。如果用户输入为 9999999+,则会出现运行时错误。

这不起作用有什么特别明确的原因吗?

哦,对了,来自 Code::Blocks 13.12 的错误消息本身:

在抛出 'std::bad_alloc' 的实例后调用终止

what(): std::bad_alloc

此应用程序已请求运行时以不寻常的方式终止它。 请联系应用程序的支持团队了解更多信息。

进程返回 3 (0x3) 执行时间:12.559 s 按任意键继续。

我有截图,但我需要 10+ 声望才能将图像放入我的问题中。

【问题讨论】:

  • 因为内存不足?
  • 我不知道,是吗?我有一台 8gb 内存机器,它的内存使用率为 34%。要跟踪的 1000 万件事情似乎微不足道,除非每个容器大约 570 字节或更多。

标签: c++ deque push-back


【解决方案1】:

这看起来像是地址空间耗尽。

如果您正在为 32 位目标进行编译,则通常每个进程的用户模式可访问地址空间被限制为 2 GiB,或者在某些平台上可能为 3 GiB。 (其余部分保留用于进程间共享的内核模式映射)

如果您在 64 位平台上运行并构建 64 位二进制文​​件,您应该能够执行更多 new/alloc() 调用,但请注意您可能会开始使用交换。

或者,即使您正在构建 64 位二进制文​​件,您也可能会达到资源配额。在 Linux 上,您可以检查 ulimit -d 以查看您是否有每个进程的内存限制。

【讨论】:

  • 这没什么大不了的。只要知道随着堆/空闲存储的增长,C/C++ 运行时库需要从操作系统请求更多地址空间。当达到人为上限或平台限制时,这些请求最终将失败,触发std::bad_alloc。您可以使用任务管理器/top/whatever 查看进程的内存使用情况,并查看它在死前有多大。您还可以尝试捕获异常并在退出之前暂停,以便在需要时更容易看到它何时死亡。
  • 老实说,我不明白你在说什么,但我会努力解决的:我在 64 位 Win7 上运行我的机器,运行 Code::Blocks 我相信是64 位 GNU GCC 编译器...当我说它不是 32 位 mingw 编译器而是另一个编译器时,我不确定我在谈论正确的事情。但我从您的评论中得到的主要内容是,如果我不将设置更改为特殊的设置,我的程序可能会有 2 GiB 的限制。这是正确的,还是说我只能在 2 GiB 内存上调用指针?
  • 啊,我看到你开始回复我删除的评论了。好的,所以我将开始使用我被告知但尚未真正开始使用的 Throw/Catch/Try 东西。我现在明白要点了,谢谢!
  • @ArnieJ 如果您不编译为 64 位目标,那么您将在 Windows 下编译为 32 位目标。 Windows 上的 32 位主机进程具有 2GB 用户可寻址虚拟地址空间的正常限制。除非您使用启用了 4GT 的 32 位版本的 Windows,或者将 IMAGE_FILE_LARGE_ADDRESS_AWARE 设置为 32 位进程的加载器选项的 64 位版本的 Windows,否则您不能寻址更多的内存。 See this for more info。 (您的代码没有 cat 类的公共构造函数;修复它。)
  • 实际上,您只是给了我足够的信息,也许可以进一步帮助您。上次我听说,MinGW 的 vanilla 版本只支持 32 位构建,所以如果你想构建 64 位二进制文​​件,你需要使用 MinGW-w64 fork 或类似的。除非您在 Visual Studio 中使用 /3gb 构建或者我在 gcc 中不知道,否则 32 位 Windows 应用程序仅允许寻址 2 GiB 内存。这很可能是您要达到的极限。
猜你喜欢
  • 2018-07-02
  • 1970-01-01
  • 2017-05-06
  • 2016-01-19
  • 2014-06-22
  • 2013-05-21
  • 2021-11-20
  • 2013-03-10
  • 2020-04-19
相关资源
最近更新 更多