【问题标题】:Trace/breakpoint trap if I free a pointer, but the same thing does not happen in the other if statements如果我释放指针,则跟踪/断点陷阱,但在其他 if 语句中不会发生同样的事情
【发布时间】:2021-01-14 11:13:37
【问题描述】:

我有这段代码(我把最重要的部分放在了):

struct card{
    char face[3];
    char suit[4];
};
typedef struct card Card;

struct stack{
    Card cardd;
    struct stack *nextPtr;
};
typedef struct stack Stack;

// prototypes:
void fill_deck(Card *deck);
void randomize_deck(Card *deck);
void make_stacks(Card *deck, Stack *stacks);
void additem(Card card, Stack **stack);
void print_stacks(Stack *stacks, Stack *basestacks);
int move_card(Stack *stacks, Stack *basestacks, unsigned int pos1, unsigned int pos2, unsigned int action);

int main(){
    SetConsoleOutputCP(65001);
    Card deck[52];
    fill_deck(deck);
    randomize_deck(deck);
    Stack *stacks = calloc(10,sizeof(Stack));
    make_stacks(deck,stacks);
    Stack *basestacks = calloc(4,sizeof(Stack));
    for(size_t i=0;i<4;++i){
        basestacks[i].nextPtr = &(basestacks[i]);
    }
    unsigned int choice;
    unsigned int pos1;
    unsigned int pos2;
    do{
        print_stacks(stacks, basestacks);
        printf("\n\nMoves available:\n");
        printf("1: Moves card from a game stack to another game stack.\n");
        printf("2: Moves card from a game stack to a base stack.\n");
        printf("3: Moves card from a base stack to a game stack.\n\n");
        printf("Insert move: ");
        scanf("%u",&choice);
        if (choice==1){
            /*
            some if for other choices
            */
        }else if (choice==3){
            printf("\nInsert starting stack: ");
            scanf("%u",&pos1);
            printf("\nInsert arrival stack: ");
            scanf("%u",&pos2);
        }
    } while (choice!=0);
}

int move_card(Stack *stacks, Stack *basestacks, unsigned int pos1, unsigned int pos2, unsigned int action){
    --pos1;
    --pos2;
    unsigned int counter_elem = 0;
    if(action==1){
    /*
    some if for other actions
    */
    } else if (action==3){
        Stack *prevfromPtr;
        Stack *fromPtr = &(basestacks[pos1]); 
        Stack *toPtr = &(stacks[pos2]); 
        while(fromPtr->nextPtr!=NULL){
            prevfromPtr = fromPtr;
            fromPtr = fromPtr->nextPtr;
            ++counter_elem;
        }
        Stack *newmovingcard = calloc(1,sizeof(Stack));
        newmovingcard->cardd = fromPtr->cardd;
        newmovingcard->nextPtr = NULL; 
        if (toPtr->nextPtr!=toPtr){
            while(toPtr->nextPtr!=NULL){ 
                toPtr = toPtr->nextPtr;
            }
            toPtr->nextPtr = newmovingcard;
            free(fromPtr);                      // bug breakpoint here
            if (counter_elem!=0){
                prevfromPtr->nextPtr = NULL;
            } else {
                basestacks[pos1].nextPtr = &(basestacks[pos1]);
            }
            return 0;
        } else { 
            toPtr->cardd = newmovingcard->cardd;
            toPtr->nextPtr = NULL;
            free(fromPtr);
            if (counter_elem!=0){
                prevfromPtr->nextPtr = NULL;
            } else {
                basestacks[pos1].nextPtr = &(basestacks[pos1]);
            }
            return 0;
            }
    }
    return -1;
}

如果您向下滚动到move_card 函数,您将在free(fromPtr) 行中看到注释。有我无法修复的错误。问题是在move_card 函数中我有3 个if 做某些事情(我只放了第三个),在前两个if 我做同样的事情(free(fromPtr))和那里工作。我不知道为什么它在第三个if 中不起作用。

这是完整的代码(cmets 和 printf 是意大利语,对不起):https://wtools.io/paste-code/b2g2 重现输入3,然后输入基本堆栈起始卡,然后到达游戏堆栈。

编辑: 如果我免费删除该行(fromPtr),它可以工作。但我不明白为什么....我不应该释放那个指针吗?

【问题讨论】:

  • 您只能释放从malloc() 返回的指针。指向数组中间的指针不能是分配的指针。
  • 您不能释放数组的一部分。完成后可以释放整个basestacks 数组。
  • @Barmar 那么如何释放所有剩余的节点呢?如果我输入 free(basestacks) 我只会释放每个堆栈的前 10 个节点。如何释放链接到这 10 个第一个节点的节点?这就是我想要做的。
  • 您的设计使这变得困难,因为您将 Stack 数组与 Stack 的动态链接列表混合在一起,有时 next 指针指向一个新分配的对象,有时它指向数组的一个元素。

标签: c pointers struct linked-list stack


【解决方案1】:

您只需在此处复制地址:Stack *fromPtr = &amp;(basestacks[pos1]);

你就不需要释放了^^

你只释放你用 malloc 或 calloc 分配的东西

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-02
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 2020-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多