【问题标题】:Sizeof operator with pointer variables带有指针变量的 Sizeof 运算符
【发布时间】:2021-04-25 04:53:19
【问题描述】:

我知道sizeof 运算符返回 C/C++ 中任何给定类型的大小。在 C 风格的数组中,数组的名称本身就是一个指针,它指向数组的第一个元素。例如,在int arr[2] = {2, 3} 中,*arr 将产生2。那为什么sizeof运算符不返回指针变量的大小,而是返回数组在内存中占用的总大小。

查看此代码:

#include <iostream>
using namespace std;

int main()
{
    int arr[10];

    cout << sizeof (arr);
    return 0;
}

输出:40 个字节(给定int 需要 4 个字节)

我想在这段代码中问的是,即使arr 只是一个指针,那么 sizeof 如何返回这个数组占用的整个大小?

我写了自己的sizeof 来理解它:

#include <iostream>
using namespace std;

template <typename T>
size_t my_sizeOf(T var)
{
    return (char *) (&var + 1) - (char *) (&var);
}

int main()
{
    int arr[10];

    cout << my_sizeOf(arr);
    return 0;
}

输出:8 字节(给定的指针变量占用 8 字节)

这段代码现在只打印指针变量的大小。我是否遗漏了有关 sizeof 运算符的一些关键点?

【问题讨论】:

标签: c++ sizeof


【解决方案1】:
#include <iostream>
using namespace std;

int main()
{
    int arr[10];

    cout << sizeof (arr); // 40
    return 0;
}

arr 只是一个指针。它是一个大小为 10 的数组。数组在传递给函数时可以衰减为指针,但类型 int[10]int* 是不同大小的不同类型。

请注意,如果我们将其强制为指针,我们会得到您期望的结果。

#include <iostream>
using namespace std;

int main()
{
    int arr[10];

    cout << sizeof ((int*)arr); // 8 (on 64-bit systems)
    return 0;
}

另一方面,如果您动态分配一个数组(您不应该这样做;99% 的时间,std::vector 更好更智能),那么您必须将它存储在指针,而不是数组变量。

#include <iostream>
using namespace std;

int main()
{
    int* arr = new int[10];

    cout << sizeof (arr); // 8 (on 64-bit systems)
    delete[] arr;
    return 0;
}

特别注意,sizeof 不是一个函数并且不评估它的参数。这是一个特殊的关键字,它只使用其参数的类型。

【讨论】:

    【解决方案2】:

    在 C++ 中,int arr[10]; 的声明将 arr 声明为 int[10] 类型,即 10 个 ints 的数组。由于数组的大小是arr 类型的一部分,sizeof 运算符知道实际大小。

    在您的函数my_sizeOf 中,您将arr 衰减为函数参数中的指针,因此您获得的是指针的大小而不是数组的大小。编写函数的正确方法是

    template <typename T, size_t N>
    size_t my_sizeOf(T (&)[N])
    {
      return N;
    }
    

    【讨论】:

    • 数组也不仅仅是 C 语言中的指针。将数组传递给 C 中的函数 always 会将其转换为指向数组第一个元素的指针。在 C++ 中也会发生同样的情况,除非数组是通过引用传递的(C 中没有这种机制)。
    • @Peter 是的,这是真的;我从答案中删除了该声明。感谢您指出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    • 2021-09-08
    • 1970-01-01
    相关资源
    最近更新 更多