0
点赞
收藏
分享

微信扫一扫

new与sizeof内存占用大小

​​1、new当个对象new在自由空间分配内存,但其无法为其分配的对象命名,因次是无名的,分配之后返回一个指向该对象的指针。int​​*p = ​​newint​​; ​​// pi指向一个动态分配的,未初始化的无名对象此new表达式在自由空间构造一个int类型对象,并返回指向该对象的指针。默认情况下,动态分配的对象是默认初始化的,这意味着内置类型或组合类型的对象的值是无定义的,而类类型对象将用默认构造函数进行初始化。 2、new(多个对象)数组new分配的对象,不管单个对象还是多个对象的分配,都是默认初始化。但可以对数组进行值初始化,方法就是:在大小之后添加一对空括号。int​​*p​​​​1​​​​ = ​​newint​​[​​10​​];    ​​// 10个未初始化intint​​*p2 = ​​newint​​[​​10​​](); ​​// 10个值初始化为0的int​​
int p3[10];//为初始化随机值

cout<<p1[0]<<" "<<p1[1]<<endl;cout<<p2[0]<<" "<<p2[1]<<endl;cout<<p3[0]<<" "<<p3[1]<<endl;

总结:
对于内置类型而言,new仅仅是分配内存,除非后面显示加(),相当于调用它的构造函数,对于自定义类型而言,只要一调用new,那么编译器不仅仅给它分配内存,还调用它的默认构造函数初始化,即使后面没有加()

#include <QCoreApplication>
#include <iostream>

using namespace std;

struct A { int m; }; // POD
struct B { ~B(){}; int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(){}; int m; }; // non-POD, default-initialising m


int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
A *aObj1 = new A;
A *aObj2 = new A();
cout << aObj1->m << endl;
cout << aObj2->m << endl;

B *bObj1 = new B;
B *bObj2 = new B();
cout << bObj1->m << endl;
cout << bObj2->m << endl;

C *cObj1 = new C;
C *cObj2 = new C();
cout << cObj1->m << endl;
cout << cObj2->m << endl;

delete aObj1;
delete aObj2;
delete bObj1;
delete bObj2;
delete cObj1;
delete cObj2;

getchar();
return a.exec();
}





#include <QCoreApplication>
#include <iostream>

using namespace std;

//#pragma pack(push)
//#pragma pack(4)

class CTest
{
public:
CTest():m_chData('\0'),m_nData(0)
{}
virtual void mem_fun(){}
virtual void mem_fun2(){}
private:
char m_chData;
int m_nData;
static char s_chData;
};
char CTest::s_chData='\0';
//#pragma pack(pop)

class CBase
{
public:
CBase() {}
};

class CBase1
{
public:
CBase1(void);
virtual ~CBase1(void);
private:
int a;
char *p;
};

class Mon
{
public:
Mon() {}
};
class Tue
{
public:
Tue() {}
};

class Wed:public Mon
{

virtual void fun()=0;
};

class Thu:public Tue,public Wed
{

};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
int *p;
char *pa;

cout<<"sizeof(char)"<<sizeof(char)<<endl;
cout<<"sizeof(int)"<<sizeof(int)<<endl;
cout<<"sizeof(long)"<<sizeof(long)<<endl;
cout<<"sizeof(long long)"<<sizeof(long long)<<endl;
cout<<"sizoef(*p)"<<sizeof(p)<<endl;
cout<<"sizoef(*pa)"<<sizeof(pa)<<endl;

cout<<"sizeof class CTest:"<<sizeof(CTest)<<endl;
cout<<"sizeof (CBase):"<<sizeof(CBase)<<endl;
cout<<"sizeof(CBase1):"<<sizeof(CBase1)<<endl;

cout<<"sizeof(Mon)"<<sizeof(Mon)<<endl;
cout<<"sizeof(Tue)"<<sizeof(Tue)<<endl;
cout<<"sizeof(Wed)"<<sizeof(Wed)<<endl;
cout<<"sizeof(Thu)"<<sizeof(Thu)<<endl;

getchar();
return a.exec();
}








总结:
空的类是会占用内存空间的,而且大小是1,原因是C++要求每个实例在内存中都有独一无二的地址。
(一)类内部的成员变量:
普通的变量:是要占用内存的,但是要注意对齐原则(这点和struct类型很相似)。
static修饰的静态变量:不占用内容,原因是编译器将其放在全局变量区。
(二)类内部的成员函数:
普通函数:不占用内存。
虚函数:要占用4个字节,用来指定虚函数的虚拟函数表的入口地址。所以一个类的虚函数所占用的地址是不变的,和虚函数的个数是没有关系的。

一般情况:
32位编译器:
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 4个字节
long long: 8个字节
unsigned long: 4个字节 64位编译器:
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int: 4个字节
unsigned int : 4个字节
float: 4个字节
double: 8个字节
long: 8个字节
long long: 8个字节
unsigned long: 8个字节



#pagma pack(2)
classA
{
inti;
unionU
{
charbuff[13];
inti;
}u;
voidfoo() { }
typedefchar* (*f)(void*);
enum{red, green, blue} color;
}a;



联合表示若干数据成员取其一,故以叠加方式分配内存,所占字节数为最大数据成员所占的字节数。 还要字节对齐

int i占4个字节
union U实例化为u占取16个字节(char数组占13个字节,但因为最大类型为int,所以占取只能为4字节的整数倍即最小16字节)
空函数不占取字节
未实例化指针不占取字节
枚举类型占取4个字节
总共占取4+16+4=24个字节
加#pragam pack(2)的话:
4+14+4=22字节

举报

相关推荐

0 条评论