2014-02-22 41 views
0

我正在做一個使用C的遊戲,我有一個函數讀取一個文件並返回一個指針,該指針保存關卡的數據。C函數返回不正確的數據

文件:levelbuilder.c

bunker *read_rooms(char *rooms_file){ 
    FILE *bunker_file = fopen(rooms_file, "r"); 
    char room_name[MAX_ROOM_NAME_LEN]; 
    fscanf(bunker_file, "%s", room_name); 
    bunker *result = create_bunker(room_name); 
    fclose(bunker_file); 
    return result; 
} 

權顯然它不會做整體水平,因爲我仍在測試的事情,我去。我將在下面列出create_bunker。

文件:room.c

bunker *create_bunker(char *room_name){ 
    bunker *result = malloc(sizeof(bunker)); 
    result->room_name = room_name; 
    for (int i = 0; i < MAX_ITEMS; i++) { 
     result->items[i] = NULL; 
    } 
    result->connected_to = NULL; 
    result->next = NULL; 
    return result; 
} 

此功能就好了。

當我使用調試器檢查read_rooms中的變量時,它們都具有來自文件的正確房間名稱。但是,主要指向級別的指針不是NULL,而是room_name。我哪裏錯了?任何幫助,將不勝感激:)

+0

從'read_rooms'返回後,您正在存儲一個指向本地堆棧變量'room_name'的指針。在函數返回後訪問它是未定義的行爲。您需要爲新對象的'room_name'字段動態分配內存並複製它。 –

+0

'result-> room_name'是什麼類型?如果它是'char *',那麼你將返回一個指向不再存在的對象的指針,因爲'room_name'(來自'read_rooms')在堆棧上創建,並且在'read_rooms'返回時不再存在。 –

回答

2

變量room_name是函數read_rooms中的本地數組。

因此,它指向堆棧上的一塊內存。

只有當您在功能「內部」時,該內存的內容纔有效。

一旦你「出來」,你不能再依靠這塊內存來包含有效的數據。

它可能包含您期望的數據,但它可能不包含。

即使這樣做,它也可能在程序執行的後期被覆蓋。的

因此而不是設置result->room_name = room_name,您應該複製的實際內容:

result->room_name = malloc(strlen(room_name)+1); 
strcpy(result->room_name,room_name); 

,當然還有,你free(result)之前不要忘記free(result->room_name) ...

+0

謝謝,它現在正在工作:D – Will

+0

不客氣:) –

0

改變這一行:

result-> ROOM_NAME = ROOM_NAME;

對於

strcpy(result-> room_name,room_name);

在result-> room_name中複製room_name的內容。就像你現在正在做的那樣,你正在做一個char *指針分配,這會讓程序變得瘋狂。

+0

這隻適用於'bunker.room_name'是一個數組,我們不知道(但?)! – alk

+0

Yeap,那是一個很好的觀察。 –

0

您在堆棧上分配room_name,比您將ponter傳遞給它,並保存到result->room_name。您不能依賴保存在堆棧上的值(不使用malloc或其他東西創建),當函數執行完成後,它很快就會被覆蓋。只需使用strcpy,如Hernan Velasquez建議的

0

一開始此行錯

result->room_name = room_name; 

因爲它會超出範圍,因此也會超出狼羣。也許做一個副本。

我確定還有其他問題