【发布时间】: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