内存分配类对象的成员函数

时间:2016-04-12 05:32:11

标签: c++ memory-management

对于一个简单的C ++程序。

#include <iostream>
#include <string>
using namespace std;

class Student
{ 
     float gpa;
     public:
     void read()
     {
         cin>>gpa;
     }

     void display()
     {
           cout<<"STUDENT GPA : "<<GPA<<endl;
     }
 };

 void main()
 {
     Student s1;
 }

对于对象s1,必须在主存储器中分配4个字节。但是当检查时,分配的内存略高于4个字节,因为成员函数,构造函数和析构函数分配了一些内存。如何计算所有函数的大小,是否可以通过减少这些额外的分配来优化代码。?

3 个答案:

答案 0 :(得分:2)

  

但是当选中时,分配的内存略高于4个字节

正确。

  

因为成员函数,构造函数和析构函数分配了一些内存。

不正确的。这是因为你的情况下的内存对齐要求,在其他情况下,因为虚函数需要某种形式的表,需要指向它的指针。构造函数和析构函数和方法的内存开销是一次性支付,而不是每个对象。

  

如何计算所有功能的大小

不是。

  

是否可以通过减少这些额外的分配来优化代码。?

当然,但这对sizeof一个对象没有影响。

答案 1 :(得分:1)

首先,这显然是实施细节。我的意思是不同的编译器或编译选项可能导致不同的值。 但由于这里没有虚函数(*),方法,构造函数和析构函数本身不需要任何空间。

并且(在修复代码中的一些错误和警告后:vec[1]应为main而不是int,而void应为GPA .. 。)仅在32位架构上显示gpa(clang版本3.4.1):

sizeof

显示......:

 int main()
 {
     Student s1;
     cout << "Size: " << sizeof(s1) << endl;
     return 0;
 }

但在64位架构上或使用Size: 4

时,它可能是8

(*)仍然是一个实现细节,但虚函数通常实现为 vtables ,意味着虚函数表。这意味着该对象包含指向对象的虚函数表(仅1个指针)的指针或直接包含该表的副本(每个虚函数一个指针)。构造函数不是虚拟的,不占用空间,但虚拟析构函数在vtable中使用一个条目。

答案 2 :(得分:1)

  

对于对象s1,必须在主存储器中分配4个字节。

他们没有。您只在单个函数中使用该对象,不使用指针或引用对其进行操作,并且它只包含一个$product字段,因此编译器可能决定将该字段存储在寄存器中,而不是存储器中。

此外,您实际上并未使用该字段,因此编译器可能根本不分配变量和字段,因为它是一种无法观察到的优化。

要显示此信息,您可以查看disassembly of your code(使用float在x64上使用clang 3.3):

-O3

请注意,所有这些代码都是将EAX寄存器清零,这只是隐式main: xorl %eax, %eax ret