带括号,括号和无内容的内存管理

时间:2018-02-11 13:17:42

标签: c++ memory

我有以下C ++程序,我用clang ++ - 5.0编译并在Ubuntu上运行:

#include <iostream>
#include <thread>
#include <chrono>
using namespace std;

constexpr int SIZE=125*1000*1024; // 125000 KB

class Point {
    int x;
    int y;
};

class Points {
    Point pointsarray[SIZE];
};

int main() {
    cout << "Before new" << endl;
    this_thread::sleep_for(chrono::seconds(3));

    auto p = new Points{};  

    cout << "After new" << endl;
    this_thread::sleep_for(chrono::seconds(5));
}

程序运行时,我使用以下方法查看可用内存:

cat /proc/meminfo | grep MemFree

我看到,正如预期的那样,声明“p = new Points {};”需要大约1,000,000 KB。

当我将此语句更改为“p = new Points();”时,会发生同样的情况。

但是,当我将其更改为“p = new Points;”时,内存消耗变为零 - 语句前后的空闲内存相同!

问题1:为什么没有parens的陈述没有记忆?

问题2:关于记忆,使用parens vs braces之间有什么区别?

2 个答案:

答案 0 :(得分:4)

在你写信之前,有些操作系统实际上并没有给你记忆。

{}()用零初始化你的结构,而缺少它们会使这些结构未初始化。
此行为对于隐式生成和=default默认构造函数是唯一的,并且无法使用用户定义的默认构造函数进行复制。

参考:cppreference/value_initialization

  

... 如果T是一个类型,其默认构造函数既不是用户提供也不是删除(也就是说,它可能是一个隐式定义的类或者默认构造函数默认构造函数),对象是零初始化然后如果它有一个非平凡的默认构造函数则默认初始化;

(强调我的)

答案 1 :(得分:4)

后一种表示法会导致点未被初始化。分配未初始化的内存非常便宜,因为它是 lazily 。出于所有实际目的,在访问分配的内存之前不会进行实际分配。

您可以通过在operator new返回并为点指定一些值后运行数组来验证这一点。然后内存消耗将突然恢复正常。

当然,所有这些都是特定于实现的,但所有“大型”现代操作系统都以这种方式工作。