C++数组和指针的sizeof结果

7
在 x86_64 架构中,指针大小为 8 字节。我认为 sizeof(x) 应该返回 8 是有道理的。我知道一个 char 是一个字节,z 数组的大小是 5 个字节。那么为什么 sizeof(z) 不返回 8 呢?
int* x = new int[10];
char z[5];

// Returns 8
std::cout << "This is the size of x: " << sizeof(x) << std::endl;

// Returns 5
std::cout << "This is the size of z: " << sizeof(z) << std::endl;

z 是一个包含 5 个字符的数组。 - Eljay
4
sizeof 是一个运算符,而不是函数。因此,当传递一个包含5个字符的数组到 sizeof 的时候,它并不会被转换为指针类型。换句话说,当把一个数组传递给 sizeof 运算符时,结果是该数组在内存中占用的绝对字节数。 - selbie
3
z的大小为5个字节,不是8、16或777。还有什么直觉吗? - n. m.
你知道吗?你可以编写模板函数来保持数组的大小。在这里查看 - user9400869
4个回答

4
你已将 x 定义为指向字符的指针,因此 sizeof(x) 给出了指向字符的指针的大小。在当前的实现中,这通常是32位或64位。一个 char 通常是8位,因此你可以期望在大多数当前编译器上 sizeof(char *) 的值为4或8。
你已将 z 定义为一个由5个字符组成的数组,因此 sizeof(z) 给出了一个由5个字符组成的数组的大小。由于数组的元素是连续的,并且sizeof(char)保证为1,显然其值为5。
例如,如果你将一个由5个字符组成的数组放入一个结构体中,然后跟随着(比如)一个 int,那么很有可能编译器会在这两个元素之间插入一些填充。

对于结构体/类中的数组,任何编译器添加的填充都不是数组本身的一部分,它跟随在数组后面,因此调用数组的 sizeof 不会包括填充。 - Remy Lebeau

4
“sizeof(z)”为什么不返回8?
因为“z”不是指针。因此,“sizeof(z)”不代表任何东西,而是5个字节。在使用“sizeof”时,数组不会转换为指针。参考:什么是数组衰变? C++中有许多隐式转换,例如:从数组到指针、从枚举到整数、从“double”到“float”、从派生类到基类、从任意指针到“void*”等。这可能会让我们想知道它们的大小是否相同。
因此,进行一个自我理解的检测方法是创建一个指针引用并尝试赋予其他类型。对于不匹配的类型,会出现错误。例如:
int *x = new int[5], *&px = x; // OK
int z[5], *&pz = z; // error: can't initialize

一个数组不就是指向其第一个元素的指针吗? - Tantillo
1
@Tantillo,不,数组不是指向其第一个元素的指针。在大多数情况下,例如索引或传递给函数时,数组会被隐式转换为指针,但这并不意味着它实际上就是指针。 - Charlim

0

当您将数组名称传递给sizeof时,您想要知道属于此数组的多少“字节”数据。

当您将指针传递给sizeof时,您想要知道此指针占用多少“字节”。

当您将数组名称作为函数参数传递时,差异非常明显。在这种情况下,函数无法看到数组占用的整个数据区域。它只能看到“指针”类型。


0

每个字符的大小都是'1' 假设您编译它时

 //It returns 1
      char z='a';
     std::cout << "This is the size of z: " << sizeof(z) << std::endl;
//It returns 5 because it is an array of 5 characters
 char z[5];
std::cout << "This is the size of z: " << sizeof(z) << std::endl;

这里还有一个检查点,请查看 https://dev59.com/1nI95IYBdhLWcg3wvwoQ - Wasim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接