此篇文章为《C++多维数组与指针》的继续讨论,原文章地址为:http://pzy84.blogbus.com/logs/10702889.html
一般都是这么认为的,我也是这样理解的。
我曾经有过的疑惑是:既然数组只是指针(而不存在“数组”这个对象),那么
1. 为什么sizeof 运算符作用于数组和指针上会得到不同的结果(显然它能区分数组和指针)?
2. delete[] 运算是怎么知道一个指针所指向的数组的长度的?
现在的理解是这样的:C++在编译时才有“数组”这个概念,运行时没有。编译时,编译器理解数组对象,因而能获取数组有、而指针没有的信息(比如用 sizeof 运算符计算数组的长度);运行时,数组退化为指针。
这个理解能够成立的必要条件是,运行时所有针对数组的操作,都可以施加到指针上,而且效果应该是完全相同的。那么事实上呢?
MSDN提到:
When an identifier of an array type appears in
an expression other than sizeof, address-of (&), or initialization of a
reference, it is converted to a pointer to the first array element.
如果数组在运行时真的退化成了指针,那么以上提到的所有需要数组对象的表达式都必须在编译时计算——的确如此。
至于 delete[] 运算符,则是利用了系统在分配内存时保存的长度信息,这个信息通常是数组数据的前面(指针向前偏移)。
总之,运行时根本没有数组长度信息可供使用(因而也不存在下标边界检查)。对于在栈上分配的数组,系统在运行不再需要知道它的长度信息,所以把这个信息给扔了。如果它是你定义的,那么你已经知道它的长度,如果它是别人作为参数传给你的,你得要求他把长度也告诉你。对于在堆上分配的数组,系统会在某个地方记录它的长度,以便于delete[]。