user-0 提问: 链式堆栈出现中断错误

回复:
user: user-1
content: 不去学习如何调试，每次遇到中断都来论坛问，就永远没有提高

user: user-2
content: 132行这里，你在for循环中调用了(ListStackPop(&head, &x) == 0)，这个方法循环后，head当前已经移动到最后一个，所以在释放时，出错。 你应该在释放前，让head取第一个节点，这样应该就没有问题了

user: user-3
content: windows： 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。  linux： 进程意外退出会在当前目录下产生‘core’文件或形如‘core.数字’的文件比如‘core.1234’ 使用命令 gdb 运行程序名 core或core.数字 进入gdb然后使用bt命令 可以查看进程意外退出前函数调用的堆栈，内容为从上到下列出对应从里层到外层的函数调用历史。 如果进程意外退出不产生core文件，参考“ulimit -c core文件最大块大小”命令

user: user-4
content: 楼主，有几处代码不对，可以参考参考下面代码： //这是一个链式堆栈的判空、压栈、出栈、取栈顶等操作 #include <stdio.h> #include <stdlib.h> #include <malloc.h>   #define MaxSize 100 #define T 1 #define F 0  typedef int DataType; typedef struct stack{ 	DataType data; 	struct stack *next; }ListStack;  //堆栈初始化  void ListStackInit(ListStack** stack) { 	if (((*stack) = (ListStack*)malloc(sizeof(ListStack))) == NULL) 	{ 		exit(1); 	} 	(*stack)->next = NULL; }  //堆栈判断是否为空  int ListStackEmpty(ListStack *stack) { 	if (stack->next == NULL) 	{ 		return 0; 	} 	else 	{ 		return 1; 	} }  //堆栈进栈  int ListStackPush(ListStack *stack, DataType x) { 	ListStack *pTemp; 	if ((pTemp = (ListStack*)malloc(sizeof(ListStack))) == NULL) 	{ 		return 0; 	} 	pTemp->data = x;  	pTemp->next = stack->next; 	stack->next = pTemp; 	return 1; }  //堆栈出栈  int ListStackPop(ListStack *stack, DataType *x) { 	ListStack *del; 	del = stack->next;//赋值 	if (del == NULL) 	{ 		return 0; 	}  	stack->next = del->next; 	*x = del->data; 	free(del); 	return 1; }  //堆栈取出栈顶  int ListStackTopPop(ListStack *stack, DataType *n) { 	if (stack->next == NULL) 	{ 		return 0; 	} 	else 	{ 		*n = stack->next->data; 		return 1; 	} }  //链表销毁 void ListDestroy(ListStack** stack) { 	ListStack *pTemp, *del;  	pTemp = *stack; 	pTemp = pTemp->next; 	while (pTemp != NULL) 	{ 		del = pTemp; 		pTemp = pTemp->next; 		free(del); 		del = NULL; 	} 	free(*stack); 	*stack = NULL; }  //主函数  int main() { 	ListStack* head; 	int x, i, m;  	ListStackInit(&head); 	for (i = 0; i < 10; i++) 	{ 		if ((ListStackPush(head, i + 1)) == 0) 		{ 			printf("插入错误\n"); 			getchar(); 			return 0; 		} 	} 	ListStackTopPop(head, &m); 	printf("栈顶=%d\n", m); 	 	for (i = 0; i < 10; i++) 	{ 		if ((ListStackPop(head, &x) == 0)) 		{ 			printf("取出错误\n"); 			getchar(); 			return 0; 		} 		else 		{ 			printf("%d   ", x); 		} 	}  	free(head); //因为前面调用了ListStackPop函数，已经把一些元素释放掉内存了，所以这里直接调用free头就可以了。 	head = NULL;  	getchar(); 	return 0; }

user: user-2
content: 引用 4 楼 qq894040717 的回复:[quote=引用 3 楼 qq_32579021 的回复:] 132行这里，你在for循环中调用了(ListStackPop(&head, &x) == 0)，这个方法循环后，head当前已经移动到最后一个，所以在释放时，出错。 你应该在释放前，让head取第一个节点，这样应该就没有问题了谢谢。解决思路是这样的。 但是把for循环用判空函数替换后，还是出现中断。请问怎么解决呢？ “while (ListStackEmpty(&head)!=0)”  [/quote]  你再“while (ListStackEmpty(&head)!=0)”  [/quote]之前，使用一个变量来保存head,之后就算head指向的路径不是第一个了，但是保存的那个变量还是指向头，最后释放的时候，将这个变量放入，而不是head.这样就又是从头开始遍历了。

user: user-0
content: 再帮我看看吧，总是在链式队列或者堆栈中出现这样的问题。 #include <stdio.h> #include <stdlib.h> #include <malloc.h>  //定义抽象数据 typedef int DataType; typedef struct queue{ 	DataType data; 	struct  queue *next; }Queue;  //定义链式队列的头尾指针 typedef struct{ 	Queue *front; 	Queue *rear; }ListQueue;  //链式队列初始化 void ListQueueInit(ListQueue *myQ) { 	myQ->front = NULL; 	myQ->rear = NULL; }  //链式队列判断是否为空 int ListQueueNoEmpty(ListQueue myQ) { 	if (myQ.front==NULL) 	{ 		return 1; 	} 	else 	{ 		return 0; 	} }  //链式队列的入队操作 int ListQueuePush(ListQueue *myQ, DataType x) { 	Queue *pTemp; 	if ((pTemp=(Queue*)malloc(sizeof(Queue)))==NULL) 	{ 		return 0; 	} 	pTemp->data = x; 	if (myQ->rear!=NULL)    //第一次入队的时候rear为null所以不执行。 	{ 		myQ->rear->next = pTemp; 	} 	myQ->rear = pTemp;     //将队尾指针指向第一个入队的元素。 	if (myQ->front==NULL) 	{ 		myQ->front = pTemp;//将队头指针指向第一个入队的元素，然后不再移动。 	} 	return 1; }  //链式队列的出队操作 int ListQueuePop(ListQueue *myQ, DataType *x) { 	ListQueue *del; 	if ((del = (ListQueue*)malloc(sizeof(ListQueue))) == NULL) 	{ 		return 0; 	} 	if (myQ->front==NULL&&myQ->rear==NULL) 	{ 		return 0; 	} 	*x = myQ->front->data; 	del->front = myQ->front; 	myQ->front = myQ->front->next; 	if (myQ->front==NULL)//如果只有一个节点 	{ 		myQ->rear = NULL; 	} 	free(del); 	return 1; }  //链式队列取队头 int ListQueueTop(ListQueue *myQ,DataType *num) { 	if (myQ->front==NULL) 	{ 		return 0; 	} 	*num = myQ->front->data; 	return 1; }   //销毁队列内存 void ListQueueDes(ListQueue **myQ) { 	ListQueue *temp,*pre; 	if ((temp = (ListQueue*)malloc(sizeof(ListQueue))) == NULL) 	{ 		exit(1); 	} 	pre = *myQ; 	while (pre!=NULL) 	{ 		temp = pre->front; 		pre->front = pre->front->next; 		free(temp); 		temp = NULL; 	} 	(*myQ)->front = NULL; 	(*myQ)->rear = NULL; }  //主函数 int main() { 	ListQueue *Q; 	int i,m; 	DataType x;  	ListQueueInit(&Q); 	for ( i = 0; i < 10; i++) 	{ 		if ((ListQueuePush(&Q, i + 1)) == 0) 		{ 			printf("1error"); 			getchar(); 			return; 		} 	} 	if ((ListQueueTop(&Q,&m))==0) 	{ 		printf("2error"); 		getchar(); 		return; 	} 	else 	{ 		printf("队头：%d\n", m); 	} 	/*while ((ListQueueNoEmpty(Q)) != 1)*/ 	i = 10; 	while (i--) 	{ 		if ((ListQueuePop(&Q,&x))==0) 		{ 			printf("3error"); 			getchar(); 			return; 		} 		else 		{ 			printf("%d    ", x); 		} 	} 	ListQueueDes(&Q); 	getchar(); 	return 0; } 引用 1 楼 user-4 的回复:楼主，有几处代码不对，可以参考参考下面代码： //这是一个链式堆栈的判空、压栈、出栈、取栈顶等操作 #include <stdio.h> #include <stdlib.h> #include <malloc.h>   #define MaxSize 100 #define T 1 #define F 0  typedef int DataType; typedef struct stack{ 	DataType data; 	struct stack *next; }ListStack;  //堆栈初始化  void ListStackInit(ListStack** stack) { 	if (((*stack) = (ListStack*)malloc(sizeof(ListStack))) == NULL) 	{ 		exit(1); 	} 	(*stack)->next = NULL; }  //堆栈判断是否为空  int ListStackEmpty(ListStack *stack) { 	if (stack->next == NULL) 	{ 		return 0; 	} 	else 	{ 		return 1; 	} }  //堆栈进栈  int ListStackPush(ListStack *stack, DataType x) { 	ListStack *pTemp; 	if ((pTemp = (ListStack*)malloc(sizeof(ListStack))) == NULL) 	{ 		return 0; 	} 	pTemp->data = x;  	pTemp->next = stack->next; 	stack->next = pTemp; 	return 1; }  //堆栈出栈  int ListStackPop(ListStack *stack, DataType *x) { 	ListStack *del; 	del = stack->next;//赋值 	if (del == NULL) 	{ 		return 0; 	}  	stack->next = del->next; 	*x = del->data; 	free(del); 	return 1; }  //堆栈取出栈顶  int ListStackTopPop(ListStack *stack, DataType *n) { 	if (stack->next == NULL) 	{ 		return 0; 	} 	else 	{ 		*n = stack->next->data; 		return 1; 	} }  //链表销毁 void ListDestroy(ListStack** stack) { 	ListStack *pTemp, *del;  	pTemp = *stack; 	pTemp = pTemp->next; 	while (pTemp != NULL) 	{ 		del = pTemp; 		pTemp = pTemp->next; 		free(del); 		del = NULL; 	} 	free(*stack); 	*stack = NULL; }  //主函数  int main() { 	ListStack* head; 	int x, i, m;  	ListStackInit(&head); 	for (i = 0; i < 10; i++) 	{ 		if ((ListStackPush(head, i + 1)) == 0) 		{ 			printf("插入错误\n"); 			getchar(); 			return 0; 		} 	} 	ListStackTopPop(head, &m); 	printf("栈顶=%d\n", m); 	 	for (i = 0; i < 10; i++) 	{ 		if ((ListStackPop(head, &x) == 0)) 		{ 			printf("取出错误\n"); 			getchar(); 			return 0; 		} 		else 		{ 			printf("%d   ", x); 		} 	}  	free(head); //因为前面调用了ListStackPop函数，已经把一些元素释放掉内存了，所以这里直接调用free头就可以了。 	head = NULL;  	getchar(); 	return 0; }

user: user-0
content: 引用 1 楼 user-4 的回复:楼主，有几处代码不对，可以参考参考下面代码： //这是一个链式堆栈的判空、压栈、出栈、取栈顶等操作 #include <stdio.h> #include <stdlib.h> #include <malloc.h>   #define MaxSize 100 #define T 1 #define F 0  typedef int DataType; typedef struct stack{ 	DataType data; 	struct stack *next; }ListStack;  //堆栈初始化  void ListStackInit(ListStack** stack) { 	if (((*stack) = (ListStack*)malloc(sizeof(ListStack))) == NULL) 	{ 		exit(1); 	} 	(*stack)->next = NULL; }  //堆栈判断是否为空  int ListStackEmpty(ListStack *stack) { 	if (stack->next == NULL) 	{ 		return 0; 	} 	else 	{ 		return 1; 	} }  //堆栈进栈  int ListStackPush(ListStack *stack, DataType x) { 	ListStack *pTemp; 	if ((pTemp = (ListStack*)malloc(sizeof(ListStack))) == NULL) 	{ 		return 0; 	} 	pTemp->data = x;  	pTemp->next = stack->next; 	stack->next = pTemp; 	return 1; }  //堆栈出栈  int ListStackPop(ListStack *stack, DataType *x) { 	ListStack *del; 	del = stack->next;//赋值 	if (del == NULL) 	{ 		return 0; 	}  	stack->next = del->next; 	*x = del->data; 	free(del); 	return 1; }  //堆栈取出栈顶  int ListStackTopPop(ListStack *stack, DataType *n) { 	if (stack->next == NULL) 	{ 		return 0; 	} 	else 	{ 		*n = stack->next->data; 		return 1; 	} }  //链表销毁 void ListDestroy(ListStack** stack) { 	ListStack *pTemp, *del;  	pTemp = *stack; 	pTemp = pTemp->next; 	while (pTemp != NULL) 	{ 		del = pTemp; 		pTemp = pTemp->next; 		free(del); 		del = NULL; 	} 	free(*stack); 	*stack = NULL; }  //主函数  int main() { 	ListStack* head; 	int x, i, m;  	ListStackInit(&head); 	for (i = 0; i < 10; i++) 	{ 		if ((ListStackPush(head, i + 1)) == 0) 		{ 			printf("插入错误\n"); 			getchar(); 			return 0; 		} 	} 	ListStackTopPop(head, &m); 	printf("栈顶=%d\n", m); 	 	for (i = 0; i < 10; i++) 	{ 		if ((ListStackPop(head, &x) == 0)) 		{ 			printf("取出错误\n"); 			getchar(); 			return 0; 		} 		else 		{ 			printf("%d   ", x); 		} 	}  	free(head); //因为前面调用了ListStackPop函数，已经把一些元素释放掉内存了，所以这里直接调用free头就可以了。 	head = NULL;  	getchar(); 	return 0; }  谢谢你，又是你来回答了。 但是把for循环用判空函数替换后，还是出现中断。请问怎么解决呢？ “while (ListStackEmpty(&head)!=0)”

user: user-0
content: 引用 3 楼 qq_32579021 的回复:132行这里，你在for循环中调用了(ListStackPop(&head, &x) == 0)，这个方法循环后，head当前已经移动到最后一个，所以在释放时，出错。 你应该在释放前，让head取第一个节点，这样应该就没有问题了谢谢。解决思路是这样的。 但是把for循环用判空函数替换后，还是出现中断。请问怎么解决呢？ “while (ListStackEmpty(&head)!=0)”