【问题标题】:how big are 1000 double?1000双有多大?
【发布时间】:2019-08-21 11:26:49
【问题描述】:

我正在学习 c++,其中一节课是关于异常处理的代码。该代码不是我的,它只是“try and catch”的示例。所以这个问题与代码质量无关

我对这段代码的问题实际上是:内存大小的输出和计算是否正确? 当我用new double(1000)分配一块内存时,大小不是8000字节吗?

cerr 输出仅计为 1kB 而不是 8kB。我错了吗?

我用sizeof(double) 得到了 1 double 的大小,以确认它是 8 个字节。

#include <iostream>
#include <cstdlib>
#include <new>
using namespace ::std;
int main()
{
    int i = 0;
    double *q;

try
{
    while (1)
    {
        q = new double[1000];
        i++;
    }
}
catch (bad_alloc &ex)
{
    cerr << "The memory is used up.  " << i
         << " Kilobyte were available." << endl;
    exit(1);
}
}

【问题讨论】:

  • new double(1000) 创建单个 double 并将其初始化为 1000new double[1000] 动态分配 1000 个双精度。 double 的大小通常为 8,但可能具有不同的大小。无论哪种方式,您的代码在每次成功分配后都会增加 i(将其增加一),因此对于每个成功分配的 1000 双倍,i 的输出值将是 1

标签: c++ exception memory out-of-memory


【解决方案1】:

总结一下@Peter 在他的评论中所说的话:您的i 变量正在计算分配次数,而不是分配的内存总量。

但是请注意,即使您“修复”了这个问题,您得到的也不是“可用内存”的数量,甚至也不是四舍五入到 8000 的倍数的可用内存数量。这是因为“可用内存”不是一个定义非常明确的概念。操作系统可能愿意让你分配数以亿计的字节;但在您开始写入到该内存之前,它实际上可能不会对其他进程执行任何可见的操作。即使您确实对其进行了写入 - 它也可以将未使用的内存页面交换到硬盘/SSD,为您正在处理的页面腾出空间。

如果您想检查使用new 可以分配的最大内存量,您可以考虑使用类似二进制搜索的过程来获取大小;我不会把它拼出来,以防这是你的作业。 (当然,这也不准确,因为其他进程的内存使用会波动。)

也可以考虑阅读:How to get available memory C++/g++?


最后,一些吹毛求疵:

  • 您使用的缩进不一致。这令人困惑。
  • i 对于变量来说不是一个好名字。 num_allocations 会更合适。当您使用更有意义的名称时,您还需要遵守其语义,这使得混淆它们变得更加困难。
  • 尽量避免像 1000 这样的“幻数”。使用enumconstexpr 定义常量。例如:enum { Kilo = 1000 };
  • 似乎没有充分的理由在这样的程序中使用 double - 这与浮点运算无关。

【讨论】:

  • @einpolkum 谢谢你的解释。这不是我的代码,它是一章末尾一个问题的解决方案。这一章其实是讲异常(try/catch),这可能是代码不太好的原因。
  • @MarioS:很公平。但请记住,阅读此问题和答案的其他人不知道/不在乎它是谁的代码 - 他们只是看到代码......所以对这些问题发表评论很重要。
【解决方案2】:

你完全正确。应该是:

cerr << "The memory is used up.  " << sizeof(double) * i
     << " Kilobyte were available." << endl;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-09
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    相关资源
    最近更新 更多