2014-07-19 94 views
-1

我嘗試用一​​種新的結構爲動態「MapNode」 S陣列,但該程序崩潰:指針崩潰的C程序

在0x000C191C在Astar.exe

未處理的異常:0000005:訪問違反讀取位置0xCCCCCCCC。

我調用getConnectedNodesArray函數,該函數調用其他兩個函數。 我知道這是某種指針問題。 當我使用數據的副本而不是試圖指向MapNode map [] [12]中的現有數據時,它就起作用了。

謝謝。

typedef struct MapNode * MapNodePointer; 


typedef struct MapNode{ 
    int x; 
    int y; 
    int value; 
    int traversable; 
    double f; 
    double g; 
    double h; 
    MapNodePointer parentNode; 
}MapNode; 


typedef struct MapNodesArray{ 
    MapNode* nodes; 
    int size; 
}MapNodesArray; 

void addNodeToEnd(MapNodesArray* arr, MapNode* p) { 
    arr->size++; 
    arr->nodes = realloc(arr->nodes, arr->size * sizeof(MapNode*)); 
    (&(arr->nodes))[arr->size - 1] = p; 
} 

MapNodesArray* NewNodesArr() { 
    MapNode *first = realloc(NULL, 0 * sizeof(MapNode)); 
    MapNodesArray temp = { first, 0 }; 
    return &temp; 
} 

MapNodesArray* getConnectedNodesArray(MapNodePointer node, MapNode map[][12]) { 
    MapNodesArray* arr = NewNodesArr(); 
    addNodeToEnd(&arr, &map[node->x - 1][node->y - 1]); 
    return arr; 
} 
+2

請發佈錯誤消息,並且其中完全程序崩潰(這函數調用等)。也請首先嚐試使用您的調試器來瀏覽程序,以便確定具體問題。 – UnholySheep

+1

提示:不要在typedefs後面隱藏指針。另外,'addNodesToEnd'看起來很狡猾...... – Deduplicator

+1

@prq:你打算來試試建議我的K&R的拷貝嗎? – geoffspear

回答

1

到底有多少內存,你認爲

MapNodesArray* NewNodesArr() { 
    MapNode *first = realloc(NULL, 0 * sizeof(MapNode)); 
    MapNodesArray temp = { first, 0 }; 
    return &temp; 
} 

將分配? (提示:根本沒有。)

此外,您正在返回一個指向本地變量的指針(通過&temp)。該東西隨着函數返回而死亡。

+0

至少重要的行不會分配任何東西... – Deduplicator

+0

我知道,但我不得不初始化它。 – user2467223

+0

@ user2467223:如何將它初始化爲'(MapNode *)NULL'?另外,指向一個超出範圍的局部變量的指針呢? – EOF

0

同意什麼EOF所說,還行

(&(arr->nodes))[arr->size - 1] = p; 
在功能addNodeToEnd

,在節點陣列外部的存儲器位置將被寫入的地址頁。這將導致內存損壞。

來說明 說變量「節點」有一個內存地址0x00000002和你已經分配了一個內存位置說0x00000050通過調用realloc。上面的語句從0x00000002獲取偏移量(arr-> size-1),而不是從0x00000050中獲取它。這是因爲您通過使用&來獲取節點的地址。形式

(arr->nodes)[arr->size - 1] = p; 

的東西會從0x00000050偏移這是你彷彿被需要。

2

你似乎害怕間接。面對它,並確保你得到你想要的數量:

typedef struct MapNode * MapNodePointer; 

以上是一個壞主意,因爲它隱藏了指針性。

typedef struct MapNodesArray{ 
    MapNode* nodes; 
    int size; 
}MapNodesArray; 

上述結構不適合存儲指向節點的指針列表。該nodes -member需要多一個明星:MapNode** nodes;

void addNodeToEnd(MapNodesArray* arr, MapNode* p) { 
    arr->size++; 
    arr->nodes = realloc(arr->nodes, arr->size * sizeof(MapNode*)); 

有一個更好的方式來表明你的內存需要的量:arr->size * sizeof *arr->nodes務必檢查分配失敗。光禿禿的人會放棄這個計劃。在此處插入:

if(!arr->nodes) abort(); 

編譯器將理所當然地抱怨下一行現在,只要刪除地址的運營商:

(&(arr->nodes))[arr->size - 1] = p; 
} 

MapNodesArray* NewNodesArr() { 
    MapNode *first = realloc(NULL, 0 * sizeof(MapNode)); 

以上線可以用MapNode* first = 0;

MapNodesArray temp = { first, 0 }; 
被替換

上面這行定義了一個自動變量,永遠不會返回一個指向它的指針。

return &temp; 
} 

oops。完全重寫:

MapNodesArray* NewNodesArr() { 
    MapNodesArray temp* = malloc(sizeof *temp); 
    *temp = (MapNodesArray){ 0, 0 }; 
    return temp; 
} 

甚至更​​好:

MapNodesArray NewNodesArr() { 
    return (MapNodesArray){ 0, 0 }; 
} 
+0

下謝謝。我修好了一切。它正在工作! – user2467223