我一直在阅读K & R关于C的书,并发现C中的指针算术允许访问超出数组末尾的一个元素。我知道C允许用记忆做任何事情,但我只是不明白,这个特点的目的是什么?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
- 1. 写作超出数组的末尾用C
- 2. C#在末尾增加一个元素的数组
- 3. C++数组索引超过了数组的末尾
- 4. 它是否是UB访问超过2d数组的行末尾的元素?
- 5. 将$ b的元素添加到数组$ a的末尾php
- 6. C-在数组末尾的神秘值
- 7. java脚本中数组末尾的未知元素?
- 8. 如何在OpenCL中将元素添加到数组的末尾?
- 9. 如何从数组的末尾截断一些元素php
- 10. Bash追加到数组元素的末尾
- 11. 将元素添加到NSMutableArray的末尾
- 12. 把元素放在TreeMap的末尾
- 13. python:读取超出文件末尾
- 14. 错误 - 索引超出列表末尾
- 15. 如何在元素的末尾淡出div的内容?
- 16. 固定元素在div末尾
- 17. GData将\添加到元素末尾
- 18. 超出数组大小元素值
- 19. 在列表的末尾插入一个元素C
- 20. C++在矢量的末尾插入元素
- 21. GZipStream超出我的数据部分末尾
- 22. 在熊猫数据框中添加一个元素到数组的末尾
- 23. 将数值推到数组的末尾
- 24. Javascript - 如何将特定索引中的元素插入到数组的末尾?
- 25. PHP推在多维数组的末尾
- 26. 在numpy数组的末尾删除dtype
- 27. 将一个元素添加到数组的末尾,从头开始删除元素以维持大小?
- 28. 添加函数void addRange(int [] array),它将新数组的元素放入现有数组的末尾?
- 29. 在C++中追加到char数组的末尾
- 30. C#LINQ追加一个项目到一个数组的末尾
另请参阅此问题:http://stackoverflow.com/questions/988158/take-the-address-of-a-one-past-the-end-array-element-via-subscript-legal-by- – 2009-06-20 14:07:03