2014-07-19 99 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