sizeof运算符
2013-06-07 17:30 夜与周公 阅读(195) 评论(0) 编辑 收藏 举报sizeof运算符是C/C++比较灵活知识点,本节总结它们的常见用法与错误。
sizeof运算符用于计算数据在内存中占有的字节数。如果sizeof运算于数组,它将会计算数组占有的内存空间。但是需要注意的是,如果采用指针在函数直接传递数据,编译器是无法知道数组的长度,因此,sizeof运算将退化成对指针的运算:
#include "stdafx.h" int funa(char my_str[100]) { cout<<sizeof(my_str)<<endl; //输出:4 } int _tmain(int argc, _TCHAR* argv[]) { char my_str[] = "l love lili"; char*p = my_str; cout<<sizeof(my_str)<<endl; //输出:12 cout<<sizeof(p)<<endl; //输出:4 system("pause"); return 0; }
那么,如何才能让程序正常输出100个字节?为了解决这个问题,需要利用C++的“数组引用”作为参数:
int funa(char (&my_str)[100]) { cout<<sizeof(my_str)<<endl; //输出:100 }
但是上面的函数也仅能接受长度为100字符数组,传入其他参数将会报错,为此,为了让程序更具有泛化能力,我们将上面的函数变成模板函数:
template<typename T, size_t N> int funa(typename (&T)[N]) { cout<<sizeof(my_str)<<endl; //输出:N }
借此机会,我们进一步讨论C++类相关的内存空间分配。首先,我们看一下空类的大小:
//Null_Class.h #ifndef CLASS_NULL #define CLASS_NULL #include "stdafx.h" class NullClass { public: void fun_a(); }; #endif //main.cpp #include "stdafx.h" #include "class.h" using namespace std; int _tmain(int argc, _TCHAR* argv[]) { NullClass null_class; cout<<sizeof(null_class); //输出:1 system("pause"); return 0; }
尽管当前类属于空类,仍然占有一个字节的内存空间。这是由于类被实例化造成的,每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址。
而对于非空类(无继承关系)其空间大小等于其成员数据的大小,需要注意的是:1)类中的static成员变量存放于全局的数据存储空间,并不占有实例化类的空间大小,2)为了快速的访问数据,编译器会对C++类中的成员变量自动内存对齐:自动按照成员函数内存最大的对齐。
// claass.h #ifndef CLASS_H #define CLASS_H #include "stdafx.h" class Base_Class { public: void fun_a(); private: int value_a;
static int value_b;
char value_c; }; #endif //main.cpp #include "stdafx.h" #include "class.h" int _tmain(int argc, _TCHAR* argv[]) { BaseClass base_class; cout<<sizeof(base_class); //输出:8 = int类型内存空间大小(4) + char类型对齐int类型的内存空间大小(4) system("pause"); return 0; }
如果类存在着继承关系,需要注意三点:1)子类的内存空间大小需要加上父类的数据成员的空间大小;2)若存在虚函数继承,需要在内存中增加一个虚函数指针的存储空间。它们在内存中的存放顺序是:虚函数指针,父类数据成员,自己的数据成员。
// class.h 文件 #ifndef CLASS_H #define CLASS_H #include "stdafx.h" class BaseClass { public: void fun_a(); virtual void fun_b(){cout<<"Base class"<<endl;} private: int value_a; static int value_c; char value_b }; class DerivateClass : public BaseClass { public: virtual void fun_b(){cout<<"Derivative Class"<<endl;}; private: int value_d; }; #endif //main.cpp文件 #include "stdafx.h" #include "class.h" int _tmain(int argc, _TCHAR* argv[]) { BaseClass base_class; DerivateClass derivate_class; cout<<sizeof(base_class)<<endl; //输出:12 = 虚函数指针长度大小(4) + int字节大小(4) +char字节对齐int字节大小(4) cout<<sizeof(derivate_class)<<endl; //输出:16 = BaseClass的大小 + 自己成员变量的大小(4) system("pause"); return 0; }