user-0 提问: 大佬快来

回复:
user: user-0
content: 引用 10 楼 cfjtaishan 的回复:printf("xxx+++++%p\n", t->next);             free(*n);             *n = NULL;             printf("+++++%p\n", t->next); 加一下这两个调试语句，可以发现执行完*n = NULL;此时t->next指向了NULL; 为什么呢，因为n指向的是t->next的地址，不是像branch2那样，m指向和t->next一样，指向堆上（malloc申请的）的空间；n指向的是t->next的地址。即t->next的首地址，那么指向*n = NULL之后，那么t->next就为NULL；（此时t指向的a为2）666，确实呆瓜了，忘了*n对n = &t->next是取解引用，所以free(*n)和free(m)效果并不一样，谢了大哥。

user: user-1
content: 建议单步跟踪程序运行，观察变量变化情况，查看指针指向内存是否有效，是否越界访问

user: user-2
content: printf("xxx+++++%p\n", t->next);             free(*n);             *n = NULL;             printf("+++++%p\n", t->next); 加一下这两个调试语句，可以发现执行完*n = NULL;此时t->next指向了NULL; 为什么呢，因为n指向的是t->next的地址，不是像branch2那样，m指向和t->next一样，指向堆上（malloc申请的）的空间；n指向的是t->next的地址。即t->next的首地址，那么指向*n = NULL之后，那么t->next就为NULL；（此时t指向的a为2）

user: user-2
content: 抱歉，没看到break

user: user-3
content: 数据结构对单链表进行数据排序 http://bbs.csdn.net/topics/392201633

user: user-2
content: 引用 2 楼 wodexiaojidan 的回复:[quote=引用 1 楼 cfjtaishan 的回复:] t->next不为NULL，但是不能保证t->next->next不为NULL，所以，当t->next->next为NULL时，(*n)->next->a就会段错误，即相当于NULL->a  所以，我认为branch 1和2都会出现段错误； 因为两个分之处理是一样的。虽然定义的结构体指针不一样。你说的段错误会出现在printf里，我把printf去掉就不会出现。现在问题是我删除的点不在末尾，所以问题不出在printf，想找出问题在哪[/quote] 你的key点在中间，但是if里的操作调过了一个节点。t->next = m->next;并且出了if之后还要执行t = t->next

user: user-0
content: *n = NULL和m = NULL，可以去掉，去掉后，branch = 1的新的下一个节点的值会被改为0

user: user-0
content: #include <stdio.h> #include <stdlib.h> #include <string.h>  typedef struct node{ 	int a; 	struct node *next; }node;  #define Branch 2  void delete(node *l, int v) { 	node **n, *t, *m;  	for(t = l; t->next != NULL; t = t->next){ 		if(t->next->a == v){ #if Branch == 1 			n = &t->next; 			 			printf("n: addr = %p, a = %d\n", *n, (*n)->a); 			//printf("n->next: addr = %p, a = %d\n", (*n)->next, (*n)->next->a); 			 			t->next = (*n)->next; 			free(*n); 			*n = NULL; #elif Branch == 2 			m = t->next; 			printf("m: addr = %p, a = %d\n", m, m->a); 			//printf("m->next: addr = %p, a = %d\n", m->next, m->next->a); 			 			t->next = m->next; 			free(m); 			m = NULL; #endif 			//printf("t->next: addr = %p, a = %d\n", t->next, t->next->a);  			break; 		} 	} }  void show(node *l) { 	node *t;  	for(t = l->next; t != NULL; t = t->next){ 		printf("addr = %p, a = %d\n", t, t->a); 	} }  node *create(void) { 	node *head = malloc(sizeof(node)); 	node *p = head;  	int i; 	for(i = 0; i < 10; ++i){ 		node *node = malloc(sizeof(node) * 1); 		node->a = i + 1; 		node->next = NULL; 		p->next = node; 		p = p->next; 	} 	p->next = NULL;  	return head; }  int main(void) { 	node *a = create(); 	 	show(a); 	delete(a, 3); 	show(a);  	return 0; }

user: user-0
content: 引用 1 楼 cfjtaishan 的回复:t->next不为NULL，但是不能保证t->next->next不为NULL，所以，当t->next->next为NULL时，(*n)->next->a就会段错误，即相当于NULL->a  所以，我认为branch 1和2都会出现段错误； 因为两个分之处理是一样的。虽然定义的结构体指针不一样。两个分支表现是，t->next新的节点会随*n变化，不会随m变化，*m被释放新节点值被清零了

user: user-4
content: n = &t->next; 这句不对吧

user: user-0
content: 引用 1 楼 cfjtaishan 的回复:t->next不为NULL，但是不能保证t->next->next不为NULL，所以，当t->next->next为NULL时，(*n)->next->a就会段错误，即相当于NULL->a  所以，我认为branch 1和2都会出现段错误； 因为两个分之处理是一样的。虽然定义的结构体指针不一样。你说的段错误会出现在printf里，我把printf去掉就不会出现。现在问题是我删除的点不在末尾，所以问题不出在printf，想找出问题在哪

user: user-2
content: t->next不为NULL，但是不能保证t->next->next不为NULL，所以，当t->next->next为NULL时，(*n)->next->a就会段错误，即相当于NULL->a  所以，我认为branch 1和2都会出现段错误； 因为两个分之处理是一样的。虽然定义的结构体指针不一样。