vs2012下运行此程序总是异常指向为“ rep stosb”这一行是怎么回事

vs2012下运行此程序总是错误指向为“ rep stosb”这一行是咋回事?
代码
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define scanf scanf_s
struct student {
char name[20];
int age;
struct student *next;
};

struct student *creat(){
struct student *h,*p1,*p2;
static int n;
h=NULL;
p1=p2=(struct student *)malloc(sizeof(struct student));
scanf("%s%d",p1->name,p1->age);
while (p1->name!=0){
n++;
if (n==1)
h=p1;
else 
p2->next=p1;
p2=p1;
p1=(struct student *)malloc(sizeof(struct student));
scanf("%s%d",p1->name,p1->age);
}
p2->next=NULL;
return h;
}
void main(){
struct student *creat();
struct student *head,*p;
head=creat();
p=head;
while(p){
printf("%s,%d",p->name,p->age);
p=p->next;
}
}


截图如下,一涉及到有字符数组的时候就有这种情况,不知是哪里出错了,求破。
vs2012下运行此程序总是异常指向为“    rep     stosb”这一行是怎么回事
------解决方案--------------------

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define scanf scanf_s
struct student {
char name[20];
int age;
struct student *next;
};

struct student *creat(){
struct student *h,*p1,*p2;
static int n;
h=NULL;
p1=p2=(struct student *)malloc(sizeof(struct student));
scanf("%s%d",p1->name,&p1->age);//输入整数要加&取地址
while (p1->name!=0){
n++;
if (n==1)
h=p1;
else 
p2->next=p1;
p2=p1;
p1=(struct student *)malloc(sizeof(struct student));
scanf("%s%d",p1->name,&p1->age);//同上
}
p2->next=NULL;
return h;
}
void main(){
struct student *creat();
struct student *head,*p;
head=creat();
p=head;
while(p){
printf("%s,%d",p->name,p->age);
p=p->next;
}
}

------解决方案--------------------
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处。

判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。

------解决方案--------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
//#define scanf scanf_s
struct student {
    char name[20];
    int age;
    struct student *next;
};

struct student *creat();

void main(){    
    struct student *head,*p;
    head = creat();
    p = head;
    while(p){
        printf("%s,%d\n",p->name,p->age);
        p = p->next;
    }
return;
}

struct student *creat(){
    struct student *h, *p1, *p2;
    static int n;
    h = NULL;
    p1 = p2 = (struct student *)malloc(sizeof(struct student));
    scanf("%s%d", p1->name, &p1->age);
    while(strcmp(p1->name, "q") != 0){
        n++;
        if(n == 1)
            h = p1;
        else 
            p2->next = p1;
        p2 = p1;
        p1 = (struct student *)malloc(sizeof(struct student));
        scanf("%s%d", p1->name, &p1->age);
    }
    p2->next=NULL;
    return h;
}

------解决方案--------------------
3个问题:
1、creat函数中n没有赋初值;
2、scanf中p1->age错误,应该为&p1->age。1楼已解决
3、建议在第一次输入之后的每次输入之前,刷新一下缓冲区,使用fflush(NULL)。
------解决方案--------------------
create中的n不用赋初值,因为它是静态变量,会在程序加载时设为0。
fflush也不需要,因为stdin和stdout是关联的,每次从stdin读时,stdout自动flush。

第18行:
while (p1->name!=0)
p1->name永远也不会等于0.

建议楼主把你导致出错的输入贴出来。
------解决方案--------------------
1、对于n,确实是我看错了,8楼正解。
3、可以要,也可以不要。

LZ的循环输入数据的代码没有终止条件,无法退出:
while (p1->name!=0)
这是因为p1->name为字符串的地址,只要从scanf获取到字符并赋予name,则p1->name不会为0,这样代码会一直进行循环,无法退出。

改了一下代码,调试成功,其中把#define scanf scanf_s删除,添加了循环输入的终止条件【随便设定的】,当输入# 1时,退出,并结合1楼的代码。修改代码如下:
#include <stdio.h>
#include <stdlib.h>