在struct和main中分配内存的区别



我有两个类似的简单结构:

struct Point{
    double x, y;
};

像这样定义有什么区别

struct Circle{
    Point *P;
    float radius;
};

和这个

struct Circle{
    Point *P = new Point;
    float radius;
};

如果我使用第一个样本并在main函数中这样做,有什么好处吗

Circle *C = new Circle;
C -> P = new Point;

这:

struct Circle{
    Point *P = new Point;
    float radius;
};

在类初始化中使用C++11。这意味着,默认情况下,如果没有其他构造函数执行其他操作(在您的示例中没有),则对于任何构造的CircleP都将设置为new Point。这与您在创建Circle之后显式设置P的示例相当,但代码行数较少。

当然,使用您提供的示例代码,您最好只使用一个值而不是指针:

struct Circle{
    Point P;
    float radius;
};

然后Circle中总会有一个Point,我们就不必就资源管理、内存泄漏等问题进行长时间的尴尬对话。

您的两个示例之间没有任何性能或行为差异,但通常情况下,您应该将资源分配(和释放)放在拥有数据的类中。这样,谁负责分配和解除分配是合乎逻辑的。

我假设这是一个简化的例子,不会建议完全删除指针。

这是C++11的一个功能:在类初始化中为非静态数据成员,并通过分配内存直接初始化指针(如果在构造函数的成员初始化列表中没有其他构造函数做同样的事情)

struct Circle{
    Point *P = new Point;
    float radius;
};

它与相当(即没有性能差异)

Circle *C = new Circle;
C -> P = new Point;

但是您应该不要同时使用这两种方法,否则会泄漏内存。不过,建议使用智能指针。

对于像Point这样的对象,我还建议将其保留为子对象,而不是指针。

这两种解决方案之间没有明显的优势,差异也很小。

然而,请认真考虑不要使用动态分配和指针来存储如此微小的数据结构[1]。这是因为动态分配不仅需要额外的时间(称为new),还需要更多的内存(在大多数操作系统中,开销为16字节或更多,并且在x86架构中,大小被四舍五入到至少16字节的边界,以允许SSE访问动态分配的内存)。因此,两个double中的16个字节现在占用了指针的8个字节和32个字节的分配空间(开销+舍入),总共占用了40个字节,比直接放置在圆对象中多了24个字节。

每次(好吧,任何函数中的第一次)访问P成员时,都需要有一个指针解引用来查找xyPoint中的位置。

您需要确保您以某种方式deletePoint对象。

当然,在某些情况下,指向小对象的指针是必要的,例如当它们具有虚拟成员函数时。

[1] 特别是因为我想说,如果没有Point来定义圆的位置,Circle对象是无用的。当对象是可选的时,有一个使用指针的参数,因为您可以使用NULL来指示它不存在。

相关内容

最新更新