简体   繁体   English

指针(?)使C程序崩溃

[英]Pointers(?) crash the C program

I try to use a new struct for a dynamic "MapNode"s array, yet the program crashes: 我尝试为动态“ MapNode”数组使用新结构,但程序崩溃:

Unhandled exception at 0x000C191C in Astar.exe: 0xC0000005: Access violation reading location 0xCCCCCCCC. Astar.exe中0x000C191C处未处理的异常:0xC0000005:访问冲突读取位置0xCCCCCCCC。

I call the getConnectedNodesArray function, which calls the other two functions. 我调用了getConnectedNodesArray函数,该函数调用了其他两个函数。 I know it's some kind of pointers problem. 我知道这是某种指针问题。 When I used copies of the data instead of trying to point to existing data in MapNode map[][12] it worked. 当我使用数据副本而不是尝试指向MapNode map [] [12]中的现有数据时,它可以工作。

Thanks. 谢谢。

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;
}

You seem to fear indirection. 您似乎害怕间接性。 Face it head-on and make sure you get exactly the amount you want: 正面面对,并确保获得所需的确切数量:

typedef struct MapNode * MapNodePointer;

The above is a bad idea, because it hides the pointer-ness. 上面是一个坏主意,因为它隐藏了指针性。

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

The above structure is no good for storing a dynmaic list of pointers to nodes. 上述结构不利于存储指向节点的动态指针列表。 The nodes -member needs one more star: MapNode** nodes; nodes成员需要MapNode** nodes;一个星: MapNode** nodes;

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

There's a better way to indicate the amount of memory you need: arr->size * sizeof *arr->nodes Always check for allocation failure. 有一种更好的方法来指示所需的内存量: arr->size * sizeof *arr->nodes始终检查分配失败。 Bare-bones would be aborting the program. 准骨将中止该程序。 Insert here: 在这里插入:

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

The compiler will rightfully complain about the next line now, just remove the address-of-operator: 现在,编译器将正确地抱怨下一行,只需删除操作者的地址即可:

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

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

The above line could be replaced with MapNode* first = 0; 上面的行可以替换为MapNode* first = 0;

    MapNodesArray temp = { first, 0 };

The above line defines an automatic variable, never return a pointer to that. 上面的代码行定义了一个自动变量,从不返回指向该变量的指针。

    return &temp;
}

oops. 哎呀 Complete rewrite: 完全重写:

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

Or even better: 甚至更好:

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

Exactly how much memory do you think 你到底想多少内存

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

will allocate? 会分配? (hint: none at all.) (提示:完全没有。)

Also, you're returning a pointer to a local variable (via &temp ). 同样,您将返回一个指向局部变量的指针(通过&temp )。 That thing dies with the function return. 那东西随着函数的返回而死亡。

Agree with what EOF has said, also the line 同意EOF所说的话,也是

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

in function addNodeToEnd, will be writing the address p in a memory location outside the the nodes array. 在addNodeToEnd函数中,将在节点数组外部的内存位置写入地址p。 This will lead to memory corruption. 这将导致内存损坏。

to illustrate say variable 'nodes' has a memory address 0x00000002 and you have assigned a memory location say 0x00000050 through the call to realloc. 举例说明,变量“节点”的内存地址为0x00000002,您通过调用realloc分配了一个内存位置,例如0x00000050。 The statement above takes the offset (arr->size-1) from 0x00000002 instead of taking it from 0x00000050. 上面的语句从0x00000002获取偏移量(arr-> size-1),而不是从0x00000050获取偏移量。 This is because you are taking the address of nodes by using &. 这是因为您要使用&来获取节点的地址。 Something of the form 形式的东西

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

will take the offset from 0x00000050 which is what you seem to be needing. 将采用您似乎需要的0x00000050的偏移量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM