类对象的成员函数的内存分配
Memory allocation of member functions of a class object
对于一个简单的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字节,因为成员函数、构造函数和析构函数分配了一些内存。!如何计算所有函数的大小,是否可以通过减少这些额外的分配来优化代码。?
但当检查时,分配的内存略高于4字节
正确。
因为成员函数、构造函数和析构函数会分配一些内存。
不正确。这是因为在您的情况下需要内存对齐,在其他情况下是因为虚拟函数需要某种形式的表,该表需要一个指向它的指针。构造函数、析构函数和方法的内存成本是一次性支付的,而不是每个对象。
所有功能的大小是如何计算的
事实并非如此。
有可能通过减少这些额外的分配来优化代码吗。?
当然,但这对sizeof
对象没有影响。
首先,这显然是一个实现细节。我的意思是,不同的编译器或编译选项可能会导致不同的值。但是,由于这里没有虚拟函数(*),因此方法、构造函数和析构函数在对象本身中不需要任何空间。
并且(在修复了代码中的一些错误和警告之后:main
应该是int
而不是void
,GPA
应该是gpa
…)只在32位架构上显示sizeof
(clang版本3.4.1:
int main()
{
Student s1;
cout << "Size: " << sizeof(s1) << endl;
return 0;
}
显示…:
Size: 4
但在64位体系结构上,或者如果使用#pragma pack(8)
,它可能是8
(*)仍然是一个实现细节,但虚拟函数通常被实现为vtables,即虚拟函数表。这意味着该对象包含指向该对象的虚拟函数表的指针(只有1个指针),或者直接包含该表的副本(每个虚拟函数一个指针)。构造函数不是虚拟的,也不占用任何空间,但虚拟析构函数使用vtable中的一个条目。
对于对象s1,必须在主内存中分配4个字节。
他们没有。您只在单个函数中使用对象,不使用指针或引用对其进行操作,并且它只包含一个float
字段,因此编译器可能决定将该字段存储在寄存器中,而不是存储在内存中。
此外,您实际上并没有使用该字段,因此编译器可能根本没有分配变量和字段,因为这是一种不可观察的优化。
要显示这一点,您可以查看代码的反汇编(在x64上使用带有-O3
的clang 3.3):
main:
xorl %eax, %eax
ret
请注意,这些代码所做的只是将EAX寄存器清零,这只是隐含的return 0;
。
- Win32编译器选项和内存分配
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 当需要超过16GB的连续内存时,内存分配失败
- 尝试摆脱任何堆内存分配
- 以下代码执行哪种内存分配(动态或静态)?
- 开放 CV 中的动态内存分配,用于视频处理
- 为什么类和 main() 函数中也有动态内存分配
- 使用 NTAllocateVirtualMemory 和 GetProcAddress 的内存分配问题不起作用
- C++:矢量分配器行为、内存分配和智能指针
- 介于 [固定数组] 和 [带内存分配的指针] 之间的性能
- Linux C++ 中的页面对齐内存分配
- 整数内存分配/释放
- 将内存分配返回值强制转换为 TYPE 数组
- C++程序什么都不做,但瓦尔格林德显示内存分配
- 给定特定内存地址的数组的动态内存分配
- 如何完成内存分配
- 我刚刚了解了C++中的动态内存分配
- 在先前调用 string::find 后添加内存分配和内存集会导致它返回 npos.为什么?
- 对于堆上的页面对齐内存分配是否有任何优化或不同的 API?
- 无法删除布尔动态内存分配