user-0 提问: 建立线性表，时而成功，时而非正常退出Process exited with return value 3221225725

回复:
user: user-0
content: 删除重复结点函数又出了问题，下面是该函数及测试代码 #include"stdio.h" #include"stdlib.h" #include"malloc.h" struct digit { 	int number; 	int type; 	struct digit *next; };  struct digit * Create() { 	int i, numb, ty = 0, n=20; 	printf("请输入顺序线性表的元素个数n："); //	scanf("%d", &n); 	printf("20\n"); 	struct digit *head = NULL;//生成头结点 ,用头指针head指向头结点  	if ((head = (struct digit *)malloc(sizeof(struct digit))) == NULL)	//分配了一个不存放有效数据的头结点  		{ 			printf("不能成功分配头结点!!\n"); 			exit(0); 		} 	struct digit *p2 = head;//永远指向尾结点 ，初始状态先赋头结点给它  	p2->next = NULL; //尾结点指针指向NULL  	struct digit *p1 = NULL; 	for (i = 1; i <= n; i++)	//循环一：建立n个结点的链表 	{	//开辟一个新结点 		if ((p1 = (struct digit *)malloc(sizeof(struct digit))) == NULL)	//分配n个int型储存块返回首地址 		{ 			printf("不能成功分配储存块!!\n"); 			exit(0); 		} 		numb=i%4+1; 		p1->next = NULL;	//令新结点指针域为NULL 		p1->number = numb;	//赋 		p1->type = ty; 		p2->next = p1;	//值，表尾链入新结点 		p1->next = NULL; 		p2 = p1;	//p2指向新的表尾结点 	} 	return head; }  struct digit * Deletesame(struct digit * head) { 	struct digit * p1=head,* p2=head,* p3=head; 	p1=p1->next; 	for(;p3->next!=NULL;) 	{ 		for(;p1!=NULL;) 		{ 			if(p3->number==p1->number)	//符合删除条件 			{ 				 				p2->next=p1->next; 				free(p1); 			//	p2=p2->next; 				p1=p2; 				p1=p1->next; 			} 			else 			{ 				p2=p1; 				p1=p1->next; 			} 		} /*		if(p3->number==p1->number)	//检测最后一个 		{ 			p2->next=NULL; 			free(p1); 			p1=NULL; 		}*/ 		p3=p3->next;	//完成一个数字的删除重复值，p3指向下一个数字 		p1=p3;p2=p3;	//p1、p2重新指向p3 		printf("ok\n");	 		p1=p1->next;	//p1往后移动1次，之后可以再次比较 	} 	return head; } void Print(struct digit * head) { 	struct digit * p = head;	//定义p指针指向链表第一个结点 	printf("	%-5s	  %-5s\n", "数值", "类型"); 	p = p->next; 	while (p != NULL) 	{ 		printf("	%-5d	 ",p->number); 		if(p->type==0)printf(" 素数\n"); 		else printf("非素数\n"); 		p = p->next;	//指向下一个节点 	} } void main() { 	struct digit * head; 	head = Create(); 	Print(head); 	head = Deletesame(head); 	printf("删除后：\n"); 	Print(head);  }  p3用于遍历链表；p1用于遍历p3后面的结点；p2用于追踪p1，方便删除结点。结果这个函数跳不出循环了。。。

user: user-0

user: user-0

user: user-0
content: 引用 5 楼 weixin_45007129 的回复:在外面定义一次指针变量，后面在循环里面逐次分配新的内存空间，并不矛盾啊。对对对我就是这个意思，没表达好

user: user-1
content: 在外面定义一次指针变量，后面在循环里面逐次分配新的内存空间，并不矛盾啊。

user: user-0
content: 谢谢！我自己解决啦~因为代码不是我写的是同学有错误不懂来问我，我急着回复没仔细看，今天花了一个小时才找出错误~~就是要在循环外定义p2（尾结点指针），不过p1是新建结点，每建一个分配一次空间给它，所以还是在for循环内定义~~感谢大佬！！！

user: user-2
content: （1）没见过这样的素数判定条件，素数的定义说的就是只有1和它本身这两个因数而已，为啥还有 m * n == numb 呢？ （2）指针 p1 、p2 定义在循环一内部，也就是说，每次进入循环一，就重新定义了两个指针变量 p1 、p2，但是又只给 p1 分配了内存空间，而没有给 p2 分配内存空间，所以从第二次的循环一开始， p2->next 就是非法的了。所以，应该把 p1 、 p2 的定义 放到循环一的前面，就跟 head 的定义 放在一起就可以了。 （3）循环二的循环，理论上存在变量 j 超出 int 的取值范围而导致循环意外退出的可能， 所以 死循环的话，建议使用 while(1)。 具体内容详见注释，自己也调试一下，看看程序运行过程中各个变量的值的情况吧。  int is_prime(int p);  struct digit *create_link_table() { 	int i, numb, j, m, ty = 0, n, nx; 	printf("请输入顺序线性表的元素个数n："); 	scanf("%d", &n); 	struct digit *head = NULL;  	// 在循环一的外面定义p1、p2 	struct digit *p1 = NULL, *p2 = NULL;  	for (i = 1; i <= n; i++) //循环一：建立n个结点的链表 	{ //开辟一个新结点 		                 //struct digit *p1 = NULL, *p2 = NULL; 		                 if ((p1 = (struct digit *)malloc(sizeof(struct digit))) == NULL) //分配n个int型储存块返回首地址 		{ 			printf("不能成功分配储存块!!\n"); 			exit(0); 		} 		p1->next = NULL; //令新结点指针域为NULL 		                 // 要用死循环的话，建议使用while(1)， 		// 下面这样的for循环，变量 j 的值有可能溢出而导致意外退出循环 		//for (j = 1; j > 0; j++) //循环二：给链表随机赋值 		while (1) { 			srand(time(NULL)); 			numb = rand() % 100001; 			if (numb >= 100 && numb <= 100000 && numb % 2 == 1) //判断是否符合100~100000、奇数 			{ 				// 判断 numb 是否为素数                                 if (is_prime(numb)) { 					p1->number = numb; 					p1->type = 1; 				} else { 					continue; 				}  				/*                                 for (m = 3; m < numb; m += 2) //循环三：判断是否为素数 				{ 					// 把元素个数变量 n 改变了，影响了循环一的条件                                         // 定义新变量 nx 					for (nx = m; m < numb; nx += 2) //循环四 					{ 						// 这是素数么？！ 						if (m * nx == numb) //若为素数，保存ty为1，跳出循环四 						{ 							ty = 1; 							break; 						} 					} 					if (ty == 1) 						break; //跳出循环三 				}                                  				p1->number = numb; //赋 				p1->type = ty;                                 */  				if (i == 1) 					head = p1; 				else 					// 每次都在循环一内部重新定义p2，但是却没有给p2分配内存空间 					p2->next = p1; //值，表尾链入新结点 				p2 = p1; //p2指向新的表尾结点 				break; //赋值成功,重新进行循环一 			} else 				continue; //随机数不符合条件，重新赋值 		} 	} 	printf("建立顺序线性表成功！\n"); 	return head; }  // 检查 p 是否为素数 int is_prime(int p) { 	if (p < 2) 		return 0;  	if (p > 2 && p % 2 == 0) 		return 0;  	int i; 	for (i = 2; i < p; i++) { 		if (p % i == 0) 			break; 	} 	if (i == p) { 		return 1; 	} else { 		return 0; 	} }