我一直在閱讀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. mmap超出文件末尾
- 5. 它是否是UB訪問超過2d數組的行末尾的元素?
- 6. 將$ b的元素添加到數組$ a的末尾php
- 7. 添加額外的文本到數組元素的末尾
- 8. 如何添加一個元素到我的數組的末尾?
- 9. C-在數組末尾的神祕值
- 10. 索引C數組的末尾
- 11. 將第二個元素索引到數組的末尾?
- 12. 如何在OpenCL中將元素添加到數組的末尾?
- 13. 手動將元素添加到提取數組的末尾
- 14. java腳本中數組末尾的未知元素?
- 15. Bash追加到數組元素的末尾
- 16. 如何從數組的末尾截斷一些元素php
- 17. 將元素添加到NSMutableArray的末尾
- 18. 把元素放在TreeMap的末尾
- 19. python:讀取超出文件末尾
- 20. 錯誤 - 索引超出列表末尾
- 21. DeflaterOutputStream:寫入超出流末尾
- 22. 鏈接列表數組索引20已超過數組的末尾(其中包含20個元素)
- 23. 如何在元素的末尾淡出div的內容?
- 24. CSS-Place元素在div末尾
- 25. GData將\添加到元素末尾
- 26. 超出數組大小元素值
- 27. C++在矢量的末尾插入元素
- 28. 在列表的末尾插入一個元素C
- 29. 在熊貓數據框中添加一個元素到數組的末尾
- 30. 參數索引超出範圍mysql在finally塊的末尾
另請參閱此問題: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