sizeof 的误解,sizeof 不是函数(function),是运算符(operator)

  函数在程序运行的时候起作用,运算符求出来的大小是在编译时就确定下来的

常见的sizeof操作

  • 对结构体类型求大小

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    typedef struct {
    char a;
    int b;
    char *ptr;
    double c;
    char name[19];
    } Demo;

    // 结构体的实际所占用内存大小,需要内存对齐,按照4byte或者8byte对齐,
    // 对齐的原则整体大小能被4整除,而且每个成员的地址偏移都是4的整数倍
    std::cout << sizeof(Demo) << std::endl;
  • 对联合体求大小

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include<stdio.h>
    // 联合体的大小是能够容纳最大的成员的大小, 还要考虑一下四字节对齐
    typedef union {
    int a[3];
    char b[8] ;
    } data;
    int main()
    {
    printf("sizeof(data)= %d\n", sizeof(data)); // 12
    return 0;
    }
  • 对字符串常量求大小

    1
    2
    3
    4
    5
    6
    7
    8
    char *p1 = "abc";
    char p2[] = "abc";
    int sz1 = sizeof("mute");
    int len1 = strlen("mute");
    int sz2 = sizeof(p1);
    int sz3 = sizeof(p2);
    int len2 = strlen(p1);
    int len3 = strlen(p2);
  • 对指针变量、指针类型求大小

    1
    2
    3
    4
    5
    6
    7
    char* ptr = "abcdefg";
    int sz1 = sizeof(ptr);
    int sz2 = sizeof(char*);
    int sz3 = sizeof(*ptr);
    // x64 平台结果是881 指针类型解引用之后的大小就是*前面类型的大小
    std::cout << sz1 << sz2 << sz3 << std::endl;
    // 通常来说sizeof 对指针类型(变量)求值x86(32bit)平台就是4Btye,x64平台就算是8Byte
  • 对含有虚函数的class求大小

  • 求数组的大小 、对变量求大小、 对类型求大小

    1
    2
    3
    4
    5
    6
    7
    8
    9
    int array[] = {10, 20, 30, 100, 200};
    // 第一种写法
    for (int i = 0; i < sizeof(array) / sizeof(int); i++) {
    std::cout << array[i] << std::endl;
    }
    // 第二种写法
    for (int i = 0; i < sizeof(array) / sizeof(array[0]); i++) {
    std::cout << array[i] << std::endl;
    }
  • sizeof 的一个考题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #include<iostream>
    using namespace std;
    struct MyStruct {
    int i;
    char str[10];
    char *ptr;
    };
    int main()
    {
    char a[3][4];
    //x86 windows (char *) type 4byte ,x64 windwows (char *)type 8bytes
    char **b[3][4]; // 指针数组,12个元素,每个指针大小4或者8
    cout<<"sizeof(MyStruct)= " << sizeof(MyStruct) << endl;
    cout<<"sizeof(a)" <<sizeof(a) << endl;
    cout<<"sizeof(b)" <<sizeof(b) << endl;
    return 0;
    }

sizeof 的原理

参考知乎用户**蓝色**的回答

x按n字节对齐的宏的来源

x = nq + r, 其中 0 <= r < n //最小非负剩余

q, r 是唯一确定的。q = [x/n], r = x - n[x/n]. 这个是带余除法的一个简单形式。在 c 语言中, q, r 容易计算出来: q = x/n, r = x % n.

所谓把 x 按 n 对齐指的是:若 r=0, 取 qn, 若 r>0, 取 (q+1)n. 这也相当于把 x 表示为:

x = nq + r’, 其中 -n < r’ <=0 //最大非正剩余

nq 是我们所求。关键是如何用 c 语言计算它。由于我们能处理标准的带余除法,所以可以把这个式子转换成一个标准的带余除法,
然后加以处理:

x+n = qn + (n+r’),其中 0<n+r’<=n //最大正剩余

x+n-1 = qn + (n+r’-1), 其中 0<= n+r’-1 <n //最小非负剩余

所以 qn = [(x+n-1)/n]n. 用 c 语言计算就是:

((x+n-1)/n)*n

若 n 是 2 的方幂, 比如 2^m,则除为右移 m 位,乘为左移 m 位。所以把 x+n-1 的最低 m 个二进制位清 0就可以了。得到:

(x+n-1) & ~(n-1)