C/C++基本型別佔用記憶體總結
阿新 • • 發佈:2018-12-09
C / C ++型別佔用記憶體總結
ç語言
Ç程式碼32位註釋
/*************************************************************************
> Description: ubuntu32位GCC4.8.4下面各變數型別大小
************************************************************************/
#include <stdio.h>
#include <string.h>
enum color {
BLACK = 0 ,
YELLOW = 1,
WHITE,
BLUE
}; //4 Byte
/*
* 位元組對齊原則:
* 1.資料型別自身的對齊值:對於char型資料,為1;對於short型,為2,對於int,float型,為4;double型別,為8,單位位元組
* 2.結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值
* 3.指定對齊值:#pragma pack (value)時的指定對齊值value。
* 4.資料成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值
* 注意:32位GCC預設指定對齊為4位元組,64位GCC預設指定對齊為8位元組
* VS2010不管是32位還是64位編譯器,其預設指定對齊值為結構體或者類的自身對齊值(成員中自身對齊值最大的值)
*/
struct person8 {
char gender; //佔用2位元組,自身1位元組
short age; //佔用2位元組
char party; //佔用4位元組,自身1位元組
int height; //佔用4位元組
char name[5]; //佔用8位元組,自身5位元組
double weight; //佔用8位元組
char addr; //佔用4位元組,自身1位元組
}; //32 Byte 有效對齊值4
struct person4 {
char gender; //佔用2位元組,自身1位元組
short age; //佔用2位元組
char party; //佔用4位元組,自身1位元組
int height; //佔用4位元組
}; //12 Byte 有效對齊值4
struct person2 {
char gender; //佔用2位元組,自身1位元組
short age; //佔用2位元組
char party; //佔用2位元組,自身1位元組
}; //6 Byte 有效對齊值2
struct person1 {
char gender; //佔用1位元組,自身1位元組
}; //1 Byte 有效對齊值1
/*
* #pragma pack(1/2/4/8)修改指定對齊位元組數
* 注意:修改並不一定能奏效,因為還要看結構中成員最大那個對齊值
* 成員最大對齊值超過指定對齊值,指定才能起作用
*/
#pragma pack(2)
struct Pragma_2
{
int a; //4
char b; //2
double c; //8
char d; //2
}; //16 Byte 有效對齊值2
#pragma pack(1)
struct Pragma_1
{
char a; //1
double b; //8
char c; //1
}; //10 Byte 有效對齊值1
#pragma pack()
typedef struct IP {
unsigned char szIP1; //high
unsigned char szIP2;
unsigned char szIP3;
unsigned char szIP4;
}IP_INT;
typedef union IP_addr {
IP_INT ip_int;
int ipv4;
char type;
}IP_ADDR; //4 Byte
static double function(int a, float b)
{
return 0;
}
int main(void)
{
char szchar = 65; //1位元組
unsigned char uszchar = 95; //1位元組
short sishort = -100; //2位元組
unsigned short usishort = 100; //2位元組
int iint = -200; //4位元組
unsigned int uiint= 200; //4位元組
float ffloat = -0.8; //4位元組
double ddouble = 99.99; //8位元組
long llong = 999; //4位元組
unsigned long ullong = 999; //4位元組
long long lllong = 9999; //8位元組
enum color color1; //4位元組
union IP_addr pc_ip; //4位元組
char* pchar; //4位元組
int* pint; //4位元組
long long* pllint; //4位元組
double* pdouble; //4位元組
double (*pffun)(int,float); //4位元組
/*
* sizeof計算大小計算整個字串長度
* strlen計算截止到'\0'的字元長度
*/
char str1[] = "12345\0678"; //str1字串加上結束符'\0'一共佔用8位元組,'\067'表示一個字元
char str2[] = "12345\\0678"; //str2字串加上結束符'\0'一共佔用11位元組,'\\'表示一個'\'字元
/* ArryNames是一個數組,故sizeof(ArryNames)大小為72位元組 */
char ArryNames[9][8] = {"Tom","Jerry","Ham","Jobs","","Benson","Nick","Evan","jiexue"};
/* names是一個指標陣列,故sizeof(names)大小為36位元組 */
const char* names[9] = {"Tom","Jerry","Ham","Jobs","","Benson","Nick","Evan","jiexue"};
printf(" ----------------------------- \n");
printf("****在%d位系統上,各型別佔用位元組數****\n", sizeof(void*) * 8);
printf("**** GCC Version: %s ****\n", __VERSION__);
printf(" ----------------------------- \n");
printf("-------------基本型別----------------\n");
printf("char: %d\n", sizeof(szchar));
printf("unsigned char: %d\n", sizeof(uszchar));
printf("short: %d\n", sizeof(sishort));
printf("unsigned short: %d\n", sizeof(usishort));
printf("int: %d\n", sizeof(iint));
printf("unsigned int: %d\n", sizeof(uiint));
printf("float: %d\n", sizeof(ffloat));
printf("double: %d\n", sizeof(ddouble));
printf("long: %d\n", sizeof(llong));
printf("unsigned long: %d\n", sizeof(ullong));
printf("long long: %d\n", sizeof(lllong));
printf("---------列舉、結構、聯合------------\n");
printf("enum: %d\n", sizeof(enum color));
printf("struct person8: %d\n", sizeof(struct person8));
printf("struct person4: %d\n", sizeof(struct person4));
printf("struct person2: %d\n", sizeof(struct person2));
printf("struct person1: %d\n", sizeof(struct person1));
printf("union IPV4: %d\n", sizeof(pc_ip));
printf("--------指標、函式、函式指標---------\n");
printf("char*: %d\n", sizeof(char*));
printf("int*: %d\n", sizeof(pint));
printf("long long*: %d\n", sizeof(pllint));
printf("double*: %d\n", sizeof(pdouble));
printf("main: %d\n", sizeof(main)); //標準C禁止這麼使用,GCC返回1,VS編譯不通過
printf("function: %d\n", sizeof(function)); //標準C禁止這麼使用,GCC返回1,VS編譯不通過
printf("&main: %d\n", sizeof(&main)); //返回4
printf("&function: %d\n", sizeof(&function)); //返回4
printf("main(): %d\n", sizeof(main())); //返回4
printf("function*: %d\n", sizeof(pffun));
printf("---------------字串----------------\n");
printf("str1[] = \"12345\\0678\": %d\n",strlen(str1));
printf("str1[] = \"12345\\0678\": %d\n", sizeof(str1));
printf("str2[] = \"12345\\\\0678\": %d\n",strlen(str2));
printf("str2[] = \"12345\\\\0678\": %d\n", sizeof(str2));
printf("char ArryNames[9][8]: %d\n", sizeof(ArryNames));
printf("char ArryNames[9][8]: %d\n", strlen(ArryNames[0])); //strlen(ArryNames)會給警告,得到的依然是3
printf("char* names[9]: %d\n", sizeof(names));
printf("------------修改對齊方式-------------\n");
printf("struct Pragma_2: %d\n", sizeof(struct Pragma_2));
printf("struct Pragma_1: %d\n", sizeof(struct Pragma_1));
getchar();
return 0;
}
輸出
-----------------------------
****在32位系統上,各型別佔用位元組數****
**** GCC Version: 4.8.4 ****
-----------------------------
-------------基本型別----------------
char: 1
unsigned char: 1
short: 2
unsigned short: 2
int: 4
unsigned int: 4
float: 4
double: 8
long: 4
unsigned long: 4
long long: 8
---------列舉、結構、聯合------------
enum: 4
struct person8: 32
struct person4: 12
struct person2: 6
struct person1: 1
union IPV4: 4
--------指標、函式、函式指標---------
char*: 4
int*: 4
long long*: 4
double*: 4
main: 1
function: 1
&main: 4
&function: 4
main(): 4
function*: 4
---------------字串----------------
str1[] = "12345\0678": 7
str1[] = "12345\0678": 8
str2[] = "12345\\0678": 10
str2[] = "12345\\0678": 11
char ArryNames[9][8]: 72
char ArryNames[9][8]: 3
char* names[9]: 36
------------修改對齊方式-------------
struct Pragma_2: 16
struct Pragma_1: 10
Ç程式碼64位註釋
/*************************************************************************
> Description: GCC4.2.1下面各變數型別大小
************************************************************************/
#include <stdio.h>
#include <string.h>
enum color {
BLACK = 0,
YELLOW = 1,
WHITE,
BLUE
}; //4 Byte
/*
* 位元組對齊原則:
* 1.資料型別自身的對齊值:對於char型資料,為1;對於short型,為2,對於int,float型,為4;double型別,為8,單位位元組
* 2.結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值
* 3.指定對齊值:#pragma pack (value)時的指定對齊值value。
* 4.資料成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值
* 注意:32位GCC預設指定對齊為4位元組,64位GCC預設指定對齊為8位元組
* VS2010不管是32位還是64位編譯器,其預設指定對齊值為結構體或者類的自身對齊值(成員中自身對齊值最大的值)
*/
struct person8 {
char gender; //佔用2位元組,自身1位元組
short age; //佔用2位元組
char party; //佔用4位元組,自身1位元組
int height; //佔用4位元組
char name[5]; //佔用12位元組,自身5位元組
double weight; //佔用8位元組
char addr; //佔用8位元組,自身1位元組
}; //40 Byte 有效對齊值8
struct person4 {
char gender; //佔用2位元組,自身1位元組
short age; //佔用2位元組
char party; //佔用4位元組,自身1位元組
int height; //佔用4位元組
}; //12 Byte 有效對齊值4
struct person2 {
char gender; //佔用2位元組,自身1位元組
short age; //佔用2位元組
char party; //佔用2位元組,自身1位元組
}; //6 Byte 有效對齊值2
struct person1 {
char gender; //佔用1位元組,自身1位元組
}; //1 Byte 有效對齊值1
/*
* #pragma pack(1/2/4/8)修改指定對齊位元組數
* 注意:修改並不一定能奏效,因為還要看結構中成員最大那個對齊值
* 成員最大對齊值超過指定對齊值,指定才能起作用
*/
#pragma pack(2)
struct Pragma_2
{
int a; //4
char b; //2
double c; //8
char d; //2
}; //16 Byte 有效對齊值2
#pragma pack(1)
struct Pragma_1
{
char a; //1
double b; //8
char c; //1
}; //10 Byte 有效對齊值1
#pragma pack()
typedef struct IP {
unsigned char szIP1; //high
unsigned char szIP2;
unsigned char szIP3;
unsigned char szIP4;
}IP_INT;
typedef union IP_addr {
IP_INT ip_int;
int ipv4;
char type;
}IP_ADDR; //4 Byte
static double function(int a, float b)
{
return 0;
}
int main(void)
{
char szchar = 65; //1位元組
unsigned char uszchar = 95; //1位元組
short sishort = -100; //2位元組
unsigned short usishort = 100; //2位元組
int iint = -200; //4位元組
unsigned int uiint= 200; //4位元組
float ffloat = -0.8; //4位元組
double ddouble = 99.99; //8位元組
long llong = 999; //8位元組
unsigned long ullong = 999; //8位元組
long long lllong = 9999; //8位元組
enum color color1; //4位元組
union IP_addr pc_ip; //4位元組
char* pchar; //8位元組
int* pint; //8位元組
long long* pllint; //8位元組
double* pdouble; //8位元組
double (*pffun)(int,float); //8位元組
/*
* sizeof計算大小計算整個字串長度
* strlen計算截止到'\0'的字元長度
*/
char str1[] = "12345\0678"; //str1字串加上結束符'\0'一共佔用8位元組,'\067'表示一個字元
char str2[] = "12345\\0678"; //str2字串加上結束符'\0'一共佔用11位元組,'\\'表示一個'\'字元
/* ArryNames是一個數組,故sizeof(ArryNames)大小為72位元組 */
char ArryNames[9][8] = {"Tom","Jerry","Ham","Jobs","","Benson","Nick","Evan","jiexue"};
/* names是一個指標陣列,故sizeof(names)大小為72位元組 */
const char* names[9] = {"Tom","Jerry","Ham","Jobs","","Benson","Nick","Evan","jiexue"};
printf(" ----------------------------- \n");
printf("****在%d位系統上,各型別佔用位元組數****\n", sizeof(void*) * 8);
printf("**** GCC Version: %s ****\n", __VERSION__);
printf(" ----------------------------- \n");
printf("-------------基本型別----------------\n");
printf("char: %d\n", sizeof(szchar));
printf("unsigned char: %d\n", sizeof(uszchar));
printf("short: %d\n", sizeof(sishort));
printf("unsigned short: %d\n", sizeof(usishort));
printf("int: %d\n", sizeof(iint));
printf("unsigned int: %d\n", sizeof(uiint));
printf("float: %d\n", sizeof(ffloat));
printf("double: %d\n", sizeof(ddouble));
printf("long: %d\n", sizeof(llong));
printf("unsigned long: %d\n", sizeof(ullong));
printf("long long: %d\n", sizeof(lllong));
printf("---------列舉、結構、聯合------------\n");
printf("enum: %d\n", sizeof(enum color));
printf("struct person8: %d\n", sizeof(struct person8));
printf("struct person4: %d\n", sizeof(struct person4));
printf("struct person2: %d\n", sizeof(struct person2));
printf("struct person1: %d\n", sizeof(struct person1));
printf("union IPV4: %d\n", sizeof(pc_ip));
printf("--------指標、函式、函式指標---------\n");
printf("char*: %d\n", sizeof(char*));
printf("int*: %d\n", sizeof(pint));
printf("long long*: %d\n", sizeof(pllint));
printf("double*: %d\n", sizeof(pdouble));
printf("main: %d\n", sizeof(main)); //標準C禁止這麼使用,GCC返回1,VS編譯不通過
printf("function: %d\n", sizeof(function)); //標準C禁止這麼使用,GCC返回1,VS編譯不通過
printf("&main: %d\n", sizeof(&main)); //返回8
printf("&function: %d\n", sizeof(&function)); //返回8
printf("main(): %d\n", sizeof(main())); //返回4
printf("function*: %d\n", sizeof(pffun));
printf("---------------字串----------------\n");
printf("str1[] = \"12345\\0678\": %d\n",strlen(str1));
printf("str1[] = \"12345\\0678\": %d\n", sizeof(str1));
printf("str2[] = \"12345\\\\0678\": %d\n",strlen(str2));
printf("str2[] = \"12345\\\\0678\": %d\n", sizeof(str2));
printf("char ArryNames[9][8]: %d\n", sizeof(ArryNames));
printf("char ArryNames[9][8]: %d\n", strlen(ArryNames[0])); //strlen(ArryNames)會給警告,得到的依然是3
printf("char* names[9]: %d\n", sizeof(names));
printf("------------修改對齊方式-------------\n");
printf("struct Pragma_2: %d\n", sizeof(struct Pragma_2));
printf("struct Pragma_1: %d\n", sizeof(struct Pragma_1));
getchar();
return 0;
}
輸出
-----------------------------
****在64位系統上,各型別佔用位元組數****
**** GCC Version: 4.2.1 ****
-----------------------------
-------------基本型別----------------
char: 1
unsigned char: 1
short: 2
unsigned short: 2
int: 4
unsigned int: 4
float: 4
double: 8
long: 8
unsigned long: 8
long long: 8
---------列舉、結構、聯合------------
enum: 4
struct person8: 40
struct person4: 12
struct person2: 6
struct person1: 1
union IPV4: 4
--------指標、函式、函式指標---------
char*: 8
int*: 8
long long*: 8
double*: 8
main: 1
function: 1
&main: 8
&function: 8
main(): 4
function*: 8
---------------字串----------------
str1[] = "12345\0678": 7
str1[] = "12345\0678": 8
str2[] = "12345\\0678": 10
str2[] = "12345\\0678": 11
char ArryNames[9][8]: 72
char ArryNames[9][8]: 3
char* names[9]: 72
------------修改對齊方式-------------
struct Pragma_2: 16
struct Pragma_1: 10
-----------------------------
****在64位系統上,各型別佔用位元組數****
**** GCC Version: 6.3.0 ****
-----------------------------
-------------基本型別----------------
char: 1
unsigned char: 1
short: 2
unsigned short: 2
int: 4
unsigned int: 4
float: 4
double: 8
long: 8
unsigned long: 8
long long: 8
---------列舉、結構、聯合------------
enum: 4
struct person8: 40
struct person4: 12
struct person2: 6
struct person1: 1
union IPV4: 4
--------指標、函式、函式指標---------
char*: 8
int*: 8
long long*: 8
double*: 8
main: 1
function: 1
&main: 8
&function: 8
main(): 4
function*: 8
---------------字串----------------
str1[] = "12345\0678": 7
str1[] = "12345\0678": 8
str2[] = "12345\\0678": 10
str2[] = "12345\\0678": 11
char ArryNames[9][8]: 72
char ArryNames[9][8]: 3
char* names[9]: 72
------------修改對齊方式-------------
struct Pragma_2: 16
struct Pragma_1: 10
-----------------------------
****在32位系統上,各型別佔用位元組數****
**** Visual Studio 2010 win32 ****
-----------------------------
-------------基本型別----------------
char: 1
unsigned char: 1
short: 2
unsigned short: 2
int: 4
unsigned int: 4
float: 4
double: 8
long: 4
unsigned long: 4
long long: 8
---------列舉、結構、聯合------------
enum: 4
struct person8: 40
struct person4: 12
struct person2: 6
struct person1: 1
union IPV4: 4
--------指標、函式、函式指標---------
char*: 4
int*: 4
long long*: 4
double*: 4
&main: 4
&function: 4
main(): 4
function*: 4
---------------字串----------------
str1[] = "12345\0678": 7
str1[] = "12345\0678": 8
str2[] = "12345\\0678": 10
str2[] = "12345\\0678": 11
char ArryNames[9][8]: 72
char ArryNames[9][8]: 3
char* names[9]: 36
------------修改對齊方式-------------
struct Pragma_2: 16
struct Pragma_1: 10
請按任意鍵繼續. . .
-----------------------------
****在64位系統上,各型別佔用位元組數****
**** Visual Studio 2010 X64 ****
-----------------------------
-------------基本型別----------------
char: 1
unsigned char: 1
short: 2
unsigned short: 2
int: 4
unsigned int: 4
float: 4
double: 8
long: 4
unsigned long: 4
long long: 8
---------列舉、結構、聯合------------
enum: 4
struct person8: 40
struct person4: 12
struct person2: 6
struct person1: 1
union IPV4: 4
--------指標、函式、函式指標---------
char*: 8
int*: 8
long long*: 8
double*: 8
&main: 8
&function: 8
main(): 4
function*: 8
---------------字串----------------
str1[] = "12345\0678": 7
str1[] = "12345\0678": 8
str2[] = "12345\\0678": 10
str2[] = "12345\\0678": 11
char ArryNames[9][8]: 72
char ArryNames[9][8]: 3
char* names[9]: 72
------------修改對齊方式-------------
struct Pragma_2: 16
struct Pragma_1: 10
請按任意鍵繼續. . .
### 總結
- 對於GCC編譯器而言,32位與64位的差別主要體現在三個方面
- 位元組32位預設以4位元組對齊,64位以8位元組對齊
- 對於指標32位佔用4位元組,64位佔用8位元組
- long型在32位上佔用4位元組,64位佔用8位元組
- 對於VS2010編譯器而言,32位與64位的區別
- 32位和64位預設都以結構體的自身對齊值對齊,除非指定比自身對齊值小的對齊值
- 對於指標32位佔用4位元組,64位佔用8位元組
- long型在32位和64位都佔用4位元組
------
## C++語言
------
### C++程式碼32位註釋
```C++
/*************************************************************************
> Description: C++基本型別、類在32位GCC4.8.4 編譯器下佔用的記憶體大小
************************************************************************/
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
using namespace std;
enum color {
BLACK = 0,
YELLOW = 1,
WHITE,
BLUE
}; //4 Byte
/*
* 位元組對齊原則:
* 1.資料型別自身的對齊值:對於char型資料,為1;對於short型,為2,對於int,float型,為4;double型別,為8,單位位元組
* 2.結構體或者類的自身對齊值:其成員中自身對齊值最大的那個值
* 3.指定對齊值:#pragma pack (value)時的指定對齊值value。
* 4.資料成員、結構體和類的有效對齊值:自身對齊值和指定對齊值中小的那個值
* 注意:32位GCC預設指定對齊為4位元組,64位GCC預設指定對齊為8位元組
* VS2010不管是32位還是64位編譯器,其預設指定對齊值為結構體或者類的自身對齊值(成員中自身對齊值最大的值)
*/
struct person8 {
char gender; //佔用2位元組,自身1位元組
short age; //佔用2位元組
char party; //佔用4位元組,自身1位元組
int height; //佔用4位元組
char name[5]; //佔用8位元組,自身5位元組
double weight; //佔用8位元組
char addr; //佔用4位元組,自身1位元組
}; //32 Byte 有效對齊值4
struct person4 {
char gender; //佔用2位元組,自身1位元組
short age; //佔用2位元組
char party; //佔用4位元組,自身1位元組
int height; //佔用4位元組
}; //12 Byte 有效對齊值4
struct person2 {
char gender; //佔用2位元組,自身1位元組
short age; //佔用2位元組
char party; //佔用2位元組,自身1位元組
}; //6 Byte 有效對齊值2
struct person1 {
char gender; //佔用1位元組,自身1位元組
}; //1 Byte 有效對齊值1
/*
* #pragma pack(1/2/4/8)修改指定對齊位元組數
* 注意:修改並不一定能奏效,因為還要看結構中成員最大那個對齊值
* 成員最大對齊值超過指定對齊值,指定才能起作用
*/
#pragma pack(2)
struct Pragma_2
{
int a; //4
char b; //2
double c; //8
char d; //2
}; //16 Byte 有效對齊值2
#pragma pack(1)
struct Pragma_1
{
char a; //1
double b; //8
char c; //1
}; //10 Byte 有效對齊值1
#pragma pack()
typedef struct IP {
unsigned char szIP1; //high
unsigned char szIP2;
unsigned char szIP3;
unsigned char szIP4;
}IP_INT;
typedef union IP_addr {
IP_INT ip_int;
int ipv4;
char type;
}IP_ADDR; //4 Byte
static double function(int a, float b)
{
return 0;
}
/*
* 1.類的大小為類的非靜態成員資料的型別大小之和,也就是說靜態成員資料不作考慮;
* 2.類的總大小也遵守類似class位元組對齊的;
* 3.成員函式都是不會被計算的;
* 4.如果是子類,那麼父類中的成員也會被計算;
* 5.虛擬函式由於要維護虛擬函式表,所以要佔據一個指標大小,也就是4位元組.
* 總結:一個類中,虛擬函式、成員函式(包括靜態與非靜態)和靜態資料成員都不佔用類物件的儲存空間
*/
class Person {
private:
unsigned short age; //佔用2位元組
bool gender; //佔用1位元組
char name[16]; //佔用17位元組
public:
/* 聯合,佔用16位元組 */
union UBffer
{
char buffer[13];
int number;
}ubuf;
typedef char*(*f)(void*); //不佔用類物件記憶體
enum{hdd,ssd,blueray}disk; //佔用4位元組,按int儲存
/* 成員函式,不佔用類物件的記憶體 */
Person(const char* name, bool gender, unsigned short age) {
strcpy(Person::name, name);
Person::gender = gender;
Person::age = age;
}
~Person() {cou