C++ c++;存储固定大小数组的大小?
这个问题是来自 考虑以下计划:C++ c++;存储固定大小数组的大小?,c++,arrays,memory-management,C++,Arrays,Memory Management,这个问题是来自 考虑以下计划: #include <iostream> #include <string> int main() { int x[10]; std::cout << sizeof(x) << std::endl; int * y = new int [10]; std::cout << sizeof(y) << std::endl; //delete [] y; } #包括 #包括 i
#include <iostream>
#include <string>
int main()
{
int x[10];
std::cout << sizeof(x) << std::endl;
int * y = new int [10];
std::cout << sizeof(y) << std::endl;
//delete [] y;
}
#包括
#包括
int main()
{
int x[10];
std::cout您有两种不同的类型:
int x[10];
这声明了一种类型int[10]
int * y;
这是指向int的指针。它的大小与系统上指针的大小相等。您的系统似乎有64位指针(现在很常见)
这里有一个在C++17中可以实现的小技巧:
template<class T>
std::enable_if_t<std::is_pointer_v<T>> foo(T ptr)
{
std::cout << "Called foo for a pointer type" << std::endl;
}
template<class T, int N>
void foo(T (&arr)[N])
{
std::cout << "Called foo for an array type of size " << N << std::endl;
}
并获得如下所示的输出:
为大小为10的数组类型调用foo
为指针类型调用foo
编辑:对分配给y
的数组大小给出了一个很好的旁白,我也要补充一点。虽然这确实是一个实现细节,但常见的是内存分配器的实现(如malloc
或new
)引擎盖下将该值写入其分配的内存块的开头。
这样,当您调用delete
时,您不必知道要删除多少字节;deallocator(free
或delete
)可以检查内存块的开头有多大。因此,分配一个字节(比如说1个字节)实际上可能会分配多个字节。(同样,这只是一种方法)数组的大小不需要存储,编译器本身知道它有多大,因为它是类型的一部分
int * y;
当你在示例中动态分配一个数组,如你使用的代码> y>代码>时,数组的大小需要存储在某处,以便Dele[]/Cord>可以做正确的事情。但是这是一个程序无法访问的实现细节。
< P>编译的C++代码中,数组的大小是明显的。(汇编程序代码)。它相当于编译时如何计算sizeof()
因此,它不存储它,编译器知道数组的大小
当您动态分配内存时,编译器再次知道数组的大小并记住它(它的实现在何处和如何定义)
,编译器知道,您不需要指定数组的大小。它根本不存储它。如果需要,请使用std::array
。它不(存储大小),编译器知道x
的完整类型,其中包括数组的大小。y
只是一个指针(不是数组)这就是编译器所知道的一切。还要注意:sizeof
是在编译时计算的,而不是在运行时。@user0042,即使std::array
也不存储大小。至少我希望实现不会这样做。对于固定大小的数组,如问题中的x[10],编译器“存储”编译代码中的大小,例如sizeof(x)在编译代码中以40为常数结束,因为正如Richard Criten所指出的,sizeof()是在编译时计算的。它是类型的一部分。int[10]
与int[8]是不同的类型
。编译器知道这些信息,因此可以得到它的大小。我喜欢这个答案,因为它带来了一些我至今不知道的东西。这不是一个糟糕的答案,但它怎么不完全等同于@MarkRansom的答案呢?@Sheljohn确实如此。我在Mark发布他的答案之前就开始写我的答案(因为我在反复检查)。。。