C元素超出数组的末尾
C不允许访问超出阵列末尾的内存。但是,它确实允许指针指向超出数组末尾的一个元素。区别很重要。
因此,这是确定:
char array[N];
char *p;
char *end;
for (p = array, end = array + N; p < end; ++p)
do_something(p);
(做*end
将是一个错误。)
和表示之所以这个功能是非常有用的:在(不存在的一个指针指向)元素在数组结束后可用于比较,比如在循环中。
从技术上讲,这是C标准允许的一切。但是,实际上,C实现(编译器和运行时)不会检查您是否访问超出数组末尾的内存,无论它是否是一个或多个元素。必须进行边界检查,这会减慢程序的执行速度。程序C的种类最适合(系统编程,通用库)比安全性和安全性边界检查更有利于速度。
这意味着C可能不是通用应用程序编程的好工具。
通常,它是表示“结束”的位置,这是一个过去的实际分配有用的,所以您可以编写代码:
char * end = begin + size;
for (char * curr = begin; curr < /* or != */ end ; ++curr) {
/* do something in the loop */
}
C标准明确地说,这个元素是一个有效的内存地址,但取消引用它仍然不是一个好主意。
它为什么有这个保证?假设您有一台内存为2^16字节的机器,地址为0000-FFFF,16位指针。假设你创建了一个16字节的数组。内存可以分配在FFF0吗?
有16个字节可用连续的,但:
begin + size == FFF0 + 10 (16 in hex) == 10000
它包装为0000,因为指针的大小。现在环路条件:
curr < end == FFF0 < 0000 == false
而不是遍历数组,循环将无所作为。这会破坏很多代码,所以C标准说分配是不允许的。
,你可以远远超出过去1阵列 为example`
int main()
{
char *string = "string";
int i = 0;
for(i=0; i< 10;i++)
{
printf("%c\n", string[i]);
}
return 0;
}
串词,无论是坐在内存前手结束后,将打印垃圾。
它可能会打印垃圾,格式化硬盘,或导致恶魔飞出你的鼻子;这是未定义行为的性质。 – aib 2009-06-20 05:57:19
另请参阅此问题:http://*.com/questions/988158/take-the-address-of-a-one-past-the-end-array-element-via-subscript-legal-by- – 2009-06-20 14:07:03