我尝试为动态" MapNode"数组使用新结构,但程序崩溃了:
Astar.exe中0x000C191C处的未处理异常:0xC0000005:访问冲突读取位置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;
}
答案 0 :(得分:2)
你似乎害怕间接。面对它,确保你得到你想要的数量:
typedef struct MapNode * MapNodePointer;
以上是一个坏主意,因为它隐藏了指针。
typedef struct MapNodesArray{
MapNode* nodes;
int size;
}MapNodesArray;
上述结构不适合存储指向节点的动态列表。 nodes
- 成员需要另外一位明星: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;
}
糟糕。完成重写:
MapNodesArray* NewNodesArr() {
MapNodesArray temp* = malloc(sizeof *temp);
*temp = (MapNodesArray){ 0, 0 };
return temp;
}
甚至更好:
MapNodesArray NewNodesArr() {
return (MapNodesArray){ 0, 0 };
}
答案 1 :(得分:1)
你认为多少内存
MapNodesArray* NewNodesArr() {
MapNode *first = realloc(NULL, 0 * sizeof(MapNode));
MapNodesArray temp = { first, 0 };
return &temp;
}
会分配吗? (提示:完全没有。)
此外,您还会返回指向局部变量的指针(通过&temp
)。那个东西因函数返回而死。
答案 2 :(得分:0)
同意EOF的说法,也就是
行(&(arr->nodes))[arr->size - 1] = p;
在函数addNodeToEnd中,将地址p写入nodes数组之外的内存位置。这将导致内存损坏。
来说明 说变量'节点'有一个内存地址0x00000002,并通过调用realloc分配了一个内存位置,如0x00000050。上面的语句从0x00000002获取偏移量(arr-> size-1),而不是从0x00000050获取。这是因为您使用&来获取节点的地址。形式的东西
(arr->nodes)[arr->size - 1] = p;
将从0x00000050获取偏移,这是您似乎需要的。