C 我删除结构条目的代码没有删除,我也不知道为什么

C 我删除结构条目的代码没有删除,我也不知道为什么,c,struct,assert,C,Struct,Assert,我现在正试着下一盘棋。然而,我发现了一个bug,如果我试图删除一个片段(当它被杀死时),程序会冻结然后退出 问题似乎出在DeletePiece函数中。我可以通过在代码中移动printf来解决这个问题,直到我可以确定它在哪里被破坏。我一想把东西放出来,它就冻住了 typedef struct { char *color; char *piece; } PIECE; PIECE *createPiece(char *color,char *piece) {

我现在正试着下一盘棋。然而,我发现了一个bug,如果我试图删除一个片段(当它被杀死时),程序会冻结然后退出

问题似乎出在DeletePiece函数中。我可以通过在代码中移动printf来解决这个问题,直到我可以确定它在哪里被破坏。我一想把东西放出来,它就冻住了

typedef struct {
        char *color;
        char *piece;
} PIECE;

PIECE *createPiece(char *color,char *piece) {

    PIECE *p=malloc(sizeof(PIECE));

    if(p==NULL) {
        printf("The memory allocation failed");
        return NULL;
    }
    else {
        p->color=malloc(2*sizeof(unsigned char));
        p->color=color;
        printf("piece is: %c \n",p->color[0]);
        p->piece=malloc(2*sizeof(unsigned char));
        p->piece=piece;
    }
}

PIECE *deletePiece(PIECE *p) {
    if(p!=NULL) {
        assert(p);
        assert(p->piece);
        assert(p->color);

        free(p->color);
        free(p->piece);
        p->color=NULL;
        p->piece=NULL;
        free(p);
    }
}
这不是在做你认为它在做的事情。第一行在内存中分配一些空间,并将其地址存储在
p->color
中;第二行用另一个地址覆盖
p->color
。分配的内存现在丢失,因为您丢失了它的地址

您可能希望将
color
的内容复制到分配给
p->color
的空间中,而不需要简单的指针分配。另外,如果您知道每次需要多少内存(
2*sizeof(unsigned char)
),为什么要动态分配内存呢?只需在结构中使用数组:

typedef struct {
    char color[2];
    char piece[2];
} PIECE;
实际上,关于动态分配片段也可以这样说。国际象棋只有32个棋子。不多也不少。只需使用一组片段:

PIECE pieces[32];

另一点我不明白,但如果不看完整的代码,我真的说不出来,那就是每种颜色和每件作品使用2个字符。我相对确信,您只需要一个字符,或者更好,一个枚举值来存储颜色或一个片段。这首先消除了对阵列的需要。

If
p!=NULL
之后断言
p
没有任何意义……您只需要一个字符作为颜色,另一个字符作为片段-它们不需要是字符串。打开编译器警告问题出现在
CreatePiece()
中<使用
malloc()
调用分配code>p->color和
p->piece
,然后立即重新分配。如果
p
被传递到
DeletePiece()
free(p->color)
free(p->piece)
的行为未定义。更糟糕的是,如果
p
不为NULL,则函数返回给调用方时不带
return
语句,这会导致调用方对
CreatePiece()
返回的值所做的任何操作都具有未定义的行为。如果所有这些问题都已解决,
DeletePiece()
将正常工作,但它也有一个返回类型并从末尾脱落。第一点是有意义的,但片段是动态分配的,因为当一个片段死亡时,我将删除它it@kunaldabomb你不需要。把它放在一边。当你在现实生活中捕捉到一个片段时,你不会毁掉它,你只是把它放在棋盘旁边。如果你每次捕捉到一个棋子时就删除它,如果你想重新开始(允许玩家再次玩),或者即使你想对AI移动进行一些回溯(如果你曾经这样做过的话),你也必须重新分配它。这是完全不必要的,并且在代码中没有任何优势。
PIECE pieces[32];