int a[5] = {1,2,3,4,5};
int* p = a;
for (; *p; p++) {
printf("%d, %d\n", *p, p);
}
這樣寫,很明顯,輸出為
1, 6684160
2, 6684164
3, 6684168
4, 6684172
5, 6684176
當我把資料結構改成char,就有點問題
char a[5] = {'1','2','3','4','5'};
char* p = a;
for (; *p; p++) {
printf("%c, %d\n", *p, p);
}
結果輸出的竟然5個之后還有亂碼
1, 6684179
2, 6684180
3, 6684181
4, 6684182
5, 6684183
, 6684184
? 6684185
e, 6684186
5之后的為何會輸出?這樣寫for回圈,*p的意思是值為0吧,指標超出陣列的下標5之后,為何還會繼續指向a[4]的下個地址?而這種情況在int型別時候卻不會出現,這是為何?
uj5u.com熱心網友回復:
第一段代碼輸出只是巧合你已經越界了
兩段代碼都是錯的
都沒有0結尾
回圈檢查0沒意義
uj5u.com熱心網友回復:
#include <stdio.h>
int main() {
int a1[6] = {1,2,3,4,5,0};
int* p1 = a1;
for (; *p1; p1++) {
printf("%d, 0x%p\n", *p1, p1);
}
char a2[6] = {'1','2','3','4','5','\0'};
char* p2 = a2;
for (; *p2; p2++) {
printf("%c, 0x%p\n", *p2, p2);
}
return 0;
}
//1, 0x0135FBE4
//2, 0x0135FBE8
//3, 0x0135FBEC
//4, 0x0135FBF0
//5, 0x0135FBF4
//1, 0x0135FBFC
//2, 0x0135FBFD
//3, 0x0135FBFE
//4, 0x0135FBFF
//5, 0x0135FC00
//
其實電腦開機后物理記憶體的每個位元組中都有值且都是可讀寫的,從來不會因為所謂的new、delete或malloc、free而被創建、銷毀。區別僅在于作業系統記憶體管理模塊在你讀寫時是否能發現并是否采取相應動作而已。作業系統管理記憶體的粒度不是位元組而是頁,一頁通常為4KB。
uj5u.com熱心網友回復:
兩段代碼的for回圈都沒結束標志,都是錯的。uj5u.com熱心網友回復:
你覺得*p1不是結束標志?
uj5u.com熱心網友回復:
我說的是題主,不是說你的。你回答是正確的。
uj5u.com熱心網友回復:
兩段代碼的for回圈都沒結束標志,都是錯的。
你覺得*p1不是結束標志?
我說的是題主,不是說你的。你回答是正確的。
題主的問題不是出在沒結束標志,而是沒顯式初始化第5個元素后面第6個元素對應的記憶體中的值,即使不宣告第6個元素,程式越界去讀第6個元素以及后面各元素時,照樣會讀第6個元素以及后面各元素對應的記憶體中的值,至于什么時候能碰到恰巧有0值,那就不一定了。
uj5u.com熱心網友回復:
這不是小問題,溢位從來就不會是小問題哦。對于用 *p 作為結束條件的,要讓最后一個值為 0,以便結束回圈
可以這樣做:
第一個
int a[6] = {1,2,3,4,5,0}
第二個
char a[6] = {'1', '2', '3', '4', '5', '\0'}
還有,建議養成好習慣,指標用完后,給它賦值NULL
就是在代碼最后加上一行 p = NULL
這樣可以在很大程度是避免形成“野指標”
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/239332.html
標籤:C語言
上一篇:業界使用的代碼掃描工具
