user-0 提问: 双向链表中内存访问错误问题.

回复:
user: user-1
content: 在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0];

user: user-0
content: 引用 3 楼 cfjtaishan 的回复:可以参考一下我写的，整个功能100多行代码可以实现的，不用对数据解析那么复杂（新学可能对C语言了解的不很透彻，就像我对JAVA了解一些表面一样）。 另外，排序也可以更简单一些。建议自己试试练练，还有问题，可以继续提出来。  谢了，我下午也一直在改善代码，已经精简了好多了，最后这个内存崩溃还是不知道什么原理，不过用scanf的%3d截取给规避掉了BUG  BUG体现就是第一次输入很长字符串然后再输入正常的学生个数后面遍历就是内存访问异常，第一次输入不太长或者直接输入正确的就不会  字符串判断主要是规定一定要数字之外无效，小数点和加减术式都不行，所以多加了一道遍历  不管怎么样作为初学者还是很感谢回答

user: user-2
content: 可以参考一下我写的，整个功能100多行代码可以实现的，不用对数据解析那么复杂（新学可能对C语言了解的不很透彻，就像我对JAVA了解一些表面一样）。 另外，排序也可以更简单一些。建议自己试试练练，还有问题，可以继续提出来。

user: user-2
content: #include <stdio.h> #include <stdlib.h> #include <string.h>  #define NEW #define     MAX_ID_NUM  12  typedef struct stu {//学生节点     struct stu *pLast;     char stuId[MAX_ID_NUM];     short stuScore;     struct stu *pNext; }Stu;  Stu *Create() {//创建链表     int num, counts;     Stu *last,*head,*current;     head = (Stu *)malloc(sizeof(Stu));     if (!head) {         fprintf(stderr, "malloc error!\n");         exit(-1);     }     head->pLast = NULL;     head->pNext = NULL;     last = head;      /*        for(;;) {//输入人数验证        printf("学生の人数（1～35）を入力してください！ \n");     //flushall();     scanf("%s", str);     length = 0;     while(str[length] != '\0')     {     length++;     }     if (length > 0 && length < 3)//判断并且验证长度     {     for(a = 0; a < length; a++)     {     if(str[a] >= 48 && str[a] <= 57) {//验证是否一定是数字     ok = 1;     } else {     ok = 0;     break;     }     }     if(ok)     {     num = atoi(str);     }     else     {     num = -1;     }      }     if(num >= 1 && num <= 35)     {     break;     }     printf("入力した人数が間違いですから、ご確認してください！ \n");     }     */     printf("学生の人数（1～35）を入力してください！ \n");     scanf("%d", &num);       for(counts = 0;counts < num;counts++)     {         current = (Stu *)malloc(sizeof(Stu));         if (!current) {             fprintf(stderr, "malloc error!\n");             exit(-1);         }         last->pNext = current;         printf("学生の番号（00001～99999）と得点（0～100）を入力してください。 \n");         /*            for(;;)            {//输入学号            printf("番号：");         //flushall();         scanf("%s",&str2);         length = 0;         while(str2[length] != '\0')         {         length++;         }         if(length>0&&length<6)         {         for(a = 0; a < length ;a++)         {         if( str2[a] >=48&&str2[a]<=57)         {         ok = 1;         }         else         {         ok = 0;         break;         }         }         if(ok)         {         id = atol(str2);         }         else         {         id = -1;         }          }         if(id>=1&&id<=99999)         {         break;         }         printf("入力した番号が間違いですから、ご確認してください！ \n");         }         */         scanf("%s", current->stuId);         printf("得点：");         scanf("%hd", ¤t->stuScore);         /*            for(;;)            {//输入分数            flushall();            scanf("%s",&str3);            length = 0;            while(str3[length] != '\0')            {            length++;            }            if(length>0&&length<4)            {            for(a = 0; a < length ;a++)            {             if( str3[a] >=48&&str3[a]<=57)            {            ok = 1;            }            else            {            ok = 0;            break;            }            }            if(ok)            {            stuScore = atoi(str3);            }            else            {            stuScore = -1;            }             }            if(stuScore>=1&&stuScore<=100)            {            break;            }            printf("入力した得点が間違いですから、ご確認してください！ \n");            }            current->stuScore = stuScore;            */         current->pLast = last;         current->pNext = NULL;         last = current;     }     return head;//debug跑到这就崩溃了。 }  void OutPut(Stu *s) {     Stu *p;     p = s;     p = p->pNext;     while (p) {         //printf("番号：%d%d%d%d%d 得点：%d \n",p->stuId[0],p->stuId[1],p->stuId[2],p->stuId[3],p->stuId[4],p->stuScore);         printf("番号：%s\t 得点：%d \n", p->stuId, p->stuScore);         p = p->pNext;     } }  void Swap(Stu *l,Stu *n) {     Stu *temp;     if(n->pNext == NULL)     {         if(l->pNext ==n)         {             n->pNext = l;             n->pLast = l->pLast;             l->pNext = NULL;             l->pLast ->pNext = n;             l->pLast = n;         }         else         {             n->pNext = l->pNext;             n->pLast->pNext =l;             temp = n->pLast;             n->pLast = l->pLast;             l->pNext->pLast = n;             l->pNext = NULL;             l->pLast->pNext = n;             l->pLast =temp;         }     }     else     {         if(l->pNext ==n)         {             n->pNext->pLast = l;             temp = n->pNext;             n->pNext = l;             n->pLast = l->pLast;             l->pNext = temp;             l->pLast->pNext = n;             l->pLast = n;         }         else         {             n->pNext->pLast = l;             temp = n->pNext;             n->pNext = l->pNext;             l->pNext->pLast = n;             l->pNext = temp;             n->pLast->pNext = l;             temp = n->pLast;             n->pLast = l->pLast;             l->pLast->pNext = n;             l->pLast = temp;         }     } }  Stu *Sort(Stu *head) {     Stu *i,*j,*k;     if(!head->pNext)         return head;     for(i = head->pNext;i->pNext != NULL;i=k->pNext)     {         for(j=i->pNext,k=i;j!=NULL;j=j->pNext)             if(k->stuScore>j->stuScore||(k->stuScore==j->stuScore&&(k->stuId[0]*10000 + k->stuId[1]*1000 + k->stuId[2]*100 + k->stuId[3]*10 + k->stuId[4]*1)>(j->stuId[0]*10000 + j->stuId[1]*1000 + j->stuId[2]*100 + j->stuId[3]*10 + j->stuId[4]*1)))                 k=j;         if(k!=i)             Swap(i,k);     }     return head; }   void MemoryFree(Stu *head) { #ifdef NEW     Stu *p, *q;      p = head;     while (p) {         q = p->next;         free(p);         p = q;     } #else     Stu *l,*n;     n=head;     while(n->pNext!=NULL)     {         l=n;         n = n->pNext;         free(l);     }  #endif }  int main() {     Stu *head = Create();     Sort(head);     OutPut(head);     MemoryFree(head);     return 0; } 学号和成绩可以直接输入，另外，你的学号长度不能超过4个数字；计算字符串长度有专门的函数。成绩可以直接用scanf %d输入 这个功能可以用10多行代码完成，所以很多代码是冗余的

user: user-1
content: 仅供参考：//不带表头结点的循环双向链表 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <time.h> #include <locale.h> struct NODE {     int          data;     struct NODE *next;     struct NODE *prev; } *head,*p,*q,*s,*p1,*p2,*q1,**ta; int i,k,n,t,m,v,N=10; int main() {     setlocale(LC_ALL,"chs");     srand(time(NULL));      head=NULL;      printf("创建%d个节点的循环双向链表:",N);//创建N个节点的循环双向链表     p=head;     for (i=0;i<N;i++) {         q=(struct NODE *)malloc(sizeof(struct NODE));         if (NULL==q) exit(1);         q->data=rand()%100;//填写0..99的随机值         q->next=NULL;         q->prev=NULL;         if (NULL==p) {             head=q;             p=head;         } else {             p->next=q;             q->prev=p;             p=q;         }     }     p->next=head;     head->prev=p;      //输出整个循环双向链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      k=3;     v=5;     printf("将值为%d的结点插入到循环双向链表的第%d个结点前:",v,k);//将值为v的结点插入到循环双向链表的第k个结点前     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=(struct NODE *)malloc(sizeof(struct NODE));             if (NULL==q) exit(1);             q->data=v;             q->next=head;             q->prev=head->prev;             head->prev->next=q;             head->prev=q;             head=q;             break;         } else {             if (k-1==n) {                 q=(struct NODE *)malloc(sizeof(struct NODE));                 if (NULL==q) exit(1);                 q->data=v;                 q->next=p->next;                 q->prev=p;                 p->next->prev=q;                 p->next=q;                 break;             }         }         p=p->next;         if (p==head) break;     }      //输出整个循环双向链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      k=5;     printf("删除第%d个节点:",k);//删除第k个节点     n=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         n++;         if (k==1) {             q=head;             head=head->next;             head->prev=q->prev;             q->prev->next=head;             if (q==head) head=NULL;             free(q);             break;         } else {             if (k-1==n) {                 q=p->next;                 p->next=q->next;                 q->next->prev=p;                 free(q);                 break;             }         }         p=p->next;         if (p==head) break;     }      //输出整个循环双向链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      printf("从小到大排序:");//从小到大排序     for (p=head;p!=NULL;) {         p1=p->prev;         for (q=p->next,q1=p;q!=NULL;) {             if (p->data > q->data) {                  //交换data //              printf("swap %02d %02d\n",p->data,q->data); //              t=p->data;p->data=q->data;q->data=t;                  //或者                  //交换prev和next //              printf("swap %02d %02d\n",p->data,q->data);                 if (p==head) {//p是头                     if (p->next==q) {//pq挨着                         head=q;                         head->prev=p1;                         p1->next=q;                         p->next=q->next;                         p->prev=q;                         q->next->prev=p;                         q->next=p;                         q=p;                         p=head;                     } else {//pq不挨着                         head=q;                         head->prev=p1;                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         p->next->prev=p;                         p->prev=q1;                         q->next->prev=p;                         q->next=p2;                         p2->prev=q;                         q1->next=p;                         q=p;                         p=head;                     }                 } else {//p不是头                     if (p->next==q) {//pq挨着                         p1->next=q;                         p->next=q->next;                         p->prev=q;                         q->next->prev=p;                         q->next=p;                         q->prev=p1;                         q=p;                         p=p1->next;                     } else {//pq不挨着                         p1->next=q;                         p2=p->next;                         p->next=q->next;                         p->prev=q->prev;                         q->next->prev=p;                         q->next=p2;                         q->prev=p1;                         p2->prev=q;                         q1->next=p;                         q=p;                         p=p1->next;                     }                 }                  //输出整个循环双向链表 //              s=head; //              while (1) { //                  if (NULL==s) { //                      printf("\n"); //                      break; //                  } //                  printf("%02d(=)",s->data); //                  if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;} //                  s=s->next; //                  if (s==head) { //                      printf(" Loop\n"); //                      break; //                  } //              } //              printf("head,p,q:%02d %02d %02d\n",head->data,p->data,q->data); //              getchar();             }             q1=q;q=q->next;             if (q==head) break;         }         p=p->next;         if (p->next==head) break;     }      //输出整个循环双向链表并计算链表长度n     n=0;     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         n++;         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      printf("将整个链表逆序:");//将整个链表逆序     if (n>=2) {         p=head;         while (1) {             q=p->prev;p->prev=p->next;p->next=q;             p=p->next;             if (p==head) break;         }     }      //输出整个循环双向链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      m=4;     n=6;     printf("将循环双向链表中前%d个结点和后%d个结点进行互换:",m,n);//将循环双向链表中前m个结点和后n个结点进行互换,m+n为链表总长     k=0;     p=head;     while (1) {         if (NULL==p) {             break;         }         k++;         if (m==k) {             q=p;             break;         }         p=p->next;         if (p==head) break;     }     head=q->next;      //输出整个循环双向链表     s=head;     while (1) {         if (NULL==s) {             printf("\n");             break;         }         printf("%02d(=)",s->data);         if (NULL!=s->next && s->next->prev!=s) {printf(" !\n");break;}         s=s->next;         if (s==head) {             printf(" Loop\n");             break;         }     }      //释放所有节点     p=head;     while (1) {         if (NULL==p) {             break;         }         q=p->next;         free(p);         p=q;         if (p==head) {             break;         }     }      return 0; } //创建10个节点的循环双向链表:12(=)46(=)31(=)63(=)25(=)91(=)39(=)02(=)92(=)68(=) Loop //将值为5的结点插入到循环双向链表的第3个结点前:12(=)46(=)05(=)31(=)63(=)25(=)91(=)39(=)02(=)92(=)68(=) Loop //删除第5个节点:12(=)46(=)05(=)31(=)25(=)91(=)39(=)02(=)92(=)68(=) Loop //从小到大排序:02(=)05(=)12(=)25(=)31(=)39(=)46(=)68(=)91(=)92(=) Loop //将整个链表逆序:92(=)91(=)68(=)46(=)39(=)31(=)25(=)12(=)05(=)02(=) Loop //将循环双向链表中前4个结点和后6个结点进行互换:39(=)31(=)25(=)12(=)05(=)02(=)92(=)91(=)68(=)46(=) Loop //