C++ C++;检查数组';通过引用传递时的大小
通过引用将数组传递给函数时,例如:C++ C++;检查数组';通过引用传递时的大小,c++,arrays,memory,C++,Arrays,Memory,通过引用将数组传递给函数时,例如: void Foo(double (&MyList)[3]); 当您尝试将大小不同于3的数组传递给此函数时,代码不会编译。 根据我在C++中已经了解的,一旦实例化数组,就不可能知道数组的大小。 编译器如何跟踪数组的大小? 那么,如果它能够检查数组的大小,为什么这样的代码仍然可以编译呢 int MyTab[3] MyTab[3] = 5; C++只能跟踪具有自动或静态存储持续时间(即本地或全局变量)的数组的大小,因为这是唯一存在固定大小数组的地方(因此
void Foo(double (&MyList)[3]);
当您尝试将大小不同于3的数组传递给此函数时,代码不会编译。
根据我在C++中已经了解的,一旦实例化数组,就不可能知道数组的大小。
编译器如何跟踪数组的大小?
那么,如果它能够检查数组的大小,为什么这样的代码仍然可以编译呢
int MyTab[3]
MyTab[3] = 5;
C++只能跟踪具有自动或静态存储持续时间(即本地或全局变量)的数组的大小,因为这是唯一存在固定大小数组的地方(因此数组类型的变量只能引用这些数组)。令人困惑的是,数组被允许衰减为指针,这种情况可能会很快发生(例如,如果您将数组作为函数参数传递,而没有将参数作为引用传递给数组) 关于你的
int MyTab[3];
MyTab[3] = 5;
例如,让我们引用:
内置的下标表达式E1[E2]与
表达式*(E1+E2)
翻译成你的情况:
MyTab[3]
与*(MyTab+3)
相同,我们可爱的指针又来了。操作符+
对指针和整数进行操作,因此MyTab
再次衰减为指针,丢失其所有大小信息
除此之外,您仍然可以通过越界访问获得结束迭代器(您只是不允许读取或写入值):
编译器确实可以警告您进行更大的越界访问,但不确定它为什么不这样做。它没有。这就是为什么在C和C++中破坏内存很容易。所有这些问题都可以通过使用<代码> STD::向量< /代码>来补救。
std::vector
具有size
成员函数。std::vector
可以通过引用传递,并且可以使用运算符[]
。@Dai:编译器确实跟踪数组大小。。。。usually@Dai:除了。。。“当通过引用将数组传递给函数时,例如:voidfoo(double(&MyList)[3]);
”,这个问题就是关于这个函数的。在本例中,它不会衰减为指针类型,因为您传递的是引用,而不是数组。如果传递了错误的大小,这将导致所有编译器出现硬编译器错误。@Dai编译器确实知道大小<代码> int [3 ] < /> >是一个与EG <代码> int [4 ] < /COD>不同的数组,不是指针。C++只能跟踪位于堆栈上的数组的大小,因为这是数组类型变量存在的唯一地方。“-关于代码> CaloC(123,sieof(char))< /Cord>?@ DA:即使在这种情况下,C++也不跟踪大小。免费存储本身就是这样。一种解决方法是使用std:array
例如auto*parray=new std::array
它占用相同的存储量,但现在编译器知道它有多少个元素。但在大多数情况下,std::vector
更好。
int i[] = new int[10]; // i is not an array, it's a pointer
int i[10]; // i is an array, the array is located on the stack
int MyTab[3];
MyTab[3] = 5;
int* begin = MyTab; // pointer decay again, equal to &MyTab[0]
int* end = &MyTab[3]; // get a pointer to one past the end (aka end iterator)