J.M*_*J.M -1 c++ memory arrays
当通过引用函数传递数组时,例如:
void Foo(double (&MyList)[3]);
Run Code Online (Sandbox Code Playgroud)
当您尝试向此函数传递大小为 3 的数组时,代码将无法编译。根据我在 C++ 中的理解,一旦实例化,就无法知道数组的大小。
编译器如何能够跟踪数组的大小?为什么那么,如果它能够检查数组的大小,这样的代码仍然可以编译?
int MyTab[3]
MyTab[3] = 5;
Run Code Online (Sandbox Code Playgroud)
C++ 只能跟踪具有自动或静态存储持续时间(即局部或全局变量)的数组的大小,因为这是唯一可以存在固定大小数组的地方(因此数组类型的变量只能引用那些)。令人困惑的部分是允许数组衰减为指针,这可能会很快发生(例如,如果您将数组作为函数参数传递而没有参数是对数组的引用)。
void foo(int i[]); // i will be a pointer, not an array
template <std::size_t N>
void foo(int (&i)[N]); // i is a reference to an array with size N
Run Code Online (Sandbox Code Playgroud)
具有动态存储期的数组(即使用 建立的数组new)不能被数组类型引用,因为这样的数组必须具有编译时已知大小并且new可以创建动态数组(大小可能仅在运行时已知)。因此,new为您提供指向数组第一个元素的指针,此时编译器无法再为您提供帮助。
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
Run Code Online (Sandbox Code Playgroud)
关于你的
int MyTab[3];
MyTab[3] = 5;
Run Code Online (Sandbox Code Playgroud)
例如,让我们引用cppreference:
内置下标表达式 E1[E2] 与表达式 *(E1 + E2) 完全相同
翻译成你的情况:
MyTab[3]是相同的,*(MyTab + 3)我们可爱的指针再次衰减。在operator+上一个指针和不可分割的,因此操作MyTab衰变再次指针,失去了所有的大小信息。
除此之外,您仍然可以通过越界访问获得结束迭代器(您只是不允许读取或写入值):
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)
Run Code Online (Sandbox Code Playgroud)
编译器确实可以警告您更大的越界访问,但不确定为什么不这样做。