2013-08-22 74 views
0

我對const char指針感到困惑。字符指針的地址變化

下面是代碼:

int main() 
{ 
    const char map[12][24]; 
    char fileName[] = "map1.txt"; 
    const char * mPtr; 
    mPtr = map; 


    printf("%d %d \n", mPtr, map); 

    load_map(fileName, map); 

    printf("%d %d \n", mPtr, map); 


    return 0; 
} 

這裏是load_map()功能代碼:

bool load_map(char * fileName, char * map) 
{ 
    FILE * fptr; 
    char c; 
    int count = 0; 

    fptr = fopen(fileName, "r"); 

    if(fptr == NULL) { 
     printf("Fail to read map \n"); 
     return false; 
    } 

    do { 

     c = fgetc(fptr); 
     *(map + count++) = c; 
     if (count % 23 == 0) continue; 
     *(map + count++) = ' '; 


    } while(c != EOF); 

    fclose(fptr); 
} 

我的問題是執行

mPtr = map; 

,當他們正好有相同的內存地址,但執行load_map()功能後 mptr的值已更改。

但是在該功能中,我沒有參考mptr。發生什麼事?

+2

使用'%p'而不是'%d'來打印指針,否則你會得到警告 – phschoen

+0

事實上,根據C的實現,你可能甚至不打印mptr的內容。你應該在你的問題中包含實際的輸出,因爲這可以提供一些見解。 –

回答

2

我相信這是未定義的行爲。

map數組聲明爲const,但是您在load_map()函數中寫入數組,但這是錯誤的。爲什麼它const,當你明顯地期望並打算通過加載數據來改變它?

+0

我認爲他試圖強調'map'地址和'mptr'值不應該改變的事實。他沒有聲明'filename',那個應該是const,'const'。 – DzungAh

1

這很可能是因爲您在map之外的數組範圍之外進行書寫,所以您寫出的數據超出範圍會溢出到mPtr變量。

另外,在main功能可變map被聲明爲數組的數組,但預期load_map它是一個char *(或一維陣列)。如果您沒有收到錯誤或至少有關於此的警告,我會感到驚訝。

+0

我認爲二維數組可以看作一個長一維數組, – good5dog5

+0

所以我用它來處理,我希望它更簡潔
也許它只是我的誤解 – good5dog5

+1

@ user2706322,二維數組是*佈局*連續的,是的,但它的類型仍然不一樣。要做你想做的事情,你必須使用指向第一個元素的指針,像'&map [0] [0]'。但是,你仍然會遇到常數問題。 –

1

您絕對應該打開編譯器提供的所有警告級別。以下行

load_map(fileName, map); 

是未定義的行爲。您正在將類型爲char const(*)[24]的指針值傳遞給期望char*的函數參數。這些是完全不同的野獸,難怪你的執行結果有點武斷。

任何像樣的現代編譯器都應該告訴你。

0
if (count % 23 == 0) continue; 

這個測試是錯誤的。您在每23個字符中的22個之後存儲空白,因此肯定會覆蓋陣列。它看起來像你真正想要的是

 map[count++] = c; 
    if ((count % 24) == 23) map[count++] = ' '; 

而且,由於你的輸入數組只有房間12組的24個字符,你應該檢查,以確保你不要去了......這只是這種代碼是黑客可以利用的盛宴,彌補了數十億美元的損失。

您還有其他一些問題,如其他答案和評論中指出的,以及一些沒有人提及的問題......例如,您在錯誤的地方檢查EOF ......閱讀沒有任何意義一個字符,將它存儲在一個數組中,然後檢查它是否是EOF。而且它是未定義的行爲(你在這個程序中有很多這樣的行爲)將EOF讀入char ...... c需要是int