代码改变世界

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;
}