为什么结构体排序调试会出现断点?

蓝莓派Alex 2018-04-28 05:10:22

今天复习C,拿着一个习题练手,检查多遍,可以确定是排序问题,但是为什么会出现调试断点?请大神告知,谢谢。



#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct MyStruct2
{
int km1, km2, km3;
float aver;
};

struct MyStruct1
{
long num;
char name[20];
struct MyStruct2 exam;
};
typedef struct MyStruct1 STU;
STU *input(STU *, int);
void print(STU *,int);
void sort(STU *, int);
int main()
{

int n = 0;
STU *s, *v;
s = (STU*)malloc(sizeof(STU));
printf("请输入学生人数:\n");
scanf("%d",&n);
v = input(s,n);
printf("原始列表:\n");
print(v, n);
sort(v,n);
printf("排序列表:\n");
print(v,n);
//free(s);
system("pause");
return 0;
}
STU *input(STU *s,int n)
{
int i;
for ( i = 0; i < n; i++)
{
printf("请分别输入学号、姓名、科目1分数、科目2分数、科目3分数(用空格隔开!)\n");
scanf("%ld%s%d%d%d",&s[i].num,&s[i].name,
&s[i].exam.km1,&s[i].exam.km2,&s[i].exam.km3);
s[i].exam.aver = (s[i].exam.km1 + s[i].exam.km2 + s[i].exam.km3) / 3;
}
return s;
}
//结构体排序

void sort(STU *s, int n)
{
STU temp;
int i,j;
for ( i = 0; i <n ; i++)
{
for ( j = 0; j < n-1-i; j++)
{
if (s[j].exam.aver < s[j+1].exam.aver)
{
temp = s[j + 1];
s[j + 1] = s[j];
s[j] = temp;
}
}
}
}

//快速排序
/*
void sort(STU *s, int l,int r)
{
if (l < r)
{
//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
int i = l, j = r;
STU x = s[l];
while (i < j)
{
while (i < j && s[j].exam.aver >= x.exam.aver) // 从右向左找第一个小于x的数
j--;
if (i < j)
s[i++] = s[j];

while (i < j && s[i].exam.aver < x.exam.aver) // 从左向右找第一个大于等于x的数
i++;
if (i < j)
s[j--] = s[i];
}
s[i] = x;
sort(s, l, i - 1); // 递归调用
sort(s, i + 1, r);
}
}
*/

void print(STU *s, int n)
{
int i;

printf("%学号\t姓名\t科目1\t科目2\t科目3\t平均分\n");
for ( i = 0; i < n; i++)
{
printf("%ld\t%s\t%d\t%d\t%d\t%.2f\n",s[i].num, s[i].name,s[i].exam.km1, s[i].exam.km2, s[i].exam.km3,s[i].exam.aver);
}
}

...全文
2548 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
蓝莓派Alex 2018-05-10
  • 打赏
  • 举报
回复
统一回复,谢谢大家的解答,非常感谢。
白色一大坨 2018-05-03
  • 打赏
  • 举报
回复
引用 7 楼 zhao4zhong1 的回复:
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。 判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
    int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]

    srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
    while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
        b[(a=rand()%11)]=0;
        Sleep(100);
        b[(a=rand()%11)]=1;
        Sleep(100);
        b[(a=rand()%11)]=2;
        Sleep(100);
        b[(a=rand()%11)]=3;
        Sleep(100);
        b[(a=rand()%11)]=4;
        Sleep(100);
    }
    return 0;
}
又出来扯淡
赵4老师 2018-05-03
  • 打赏
  • 举报
回复
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。 判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
    int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]

    srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
    while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
        b[(a=rand()%11)]=0;
        Sleep(100);
        b[(a=rand()%11)]=1;
        Sleep(100);
        b[(a=rand()%11)]=2;
        Sleep(100);
        b[(a=rand()%11)]=3;
        Sleep(100);
        b[(a=rand()%11)]=4;
        Sleep(100);
    }
    return 0;
}
strangejie 2018-05-03
  • 打赏
  • 举报
回复
int main() { int n = 0; STU *s, *v; printf("请输入学生人数:\n"); scanf("%d",&n); s = (STU*)malloc(n*sizeof(STU)); if (!s) exit(0); v = input(s,n); printf("原始列表:\n"); print(v, n); sort(v,0,n); printf("排序列表:\n"); print(v,n); //free(s); system("pause"); return 0; } 这段里面sort(v,0,n)改成sort(v,0,n-1); 这个错误很致命; STU *input(STU *s,int n) { int i; for ( i = 0; i < n; i++) { printf("请分别输入学号、姓名、科目1分数、科目2分数、科目3分数(用空格隔开!)\n"); scanf("%ld%s%d%d%d",&s[i].num,&s[i].name, &s[i].exam.km1,&s[i].exam.km2,&s[i].exam.km3); s[i].exam.aver = (s[i].exam.km1 + s[i].exam.km2 + s[i].exam.km3) / 3; } return s; } 这段格式字符之间要加空格,因为你自己要求输入之间要加空格,而且&s[i].name这个是什么东东,这是要把name数组的首地址给改了? 都是细节。
赵4老师 2018-05-03
  • 打赏
  • 举报
回复
引用 8 楼 phenix2009 的回复:
[quote=引用 7 楼 zhao4zhong1 的回复:] 崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。 判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h>
#include <stdlib.h>
#include <windows.h>
int main() {
    int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]

    srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
    while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
        b[(a=rand()%11)]=0;
        Sleep(100);
        b[(a=rand()%11)]=1;
        Sleep(100);
        b[(a=rand()%11)]=2;
        Sleep(100);
        b[(a=rand()%11)]=3;
        Sleep(100);
        b[(a=rand()%11)]=4;
        Sleep(100);
    }
    return 0;
}
又出来扯淡[/quote] 充分证明你根本不会使用数据断点来定位越界访问。
白色一大坨 2018-05-02
  • 打赏
  • 举报
回复
越界了,调用排序时候改一下参数即可:

	int n = 0;
	STU *s, *v;
	printf("请输入学生人数:\n");
	scanf("%d", &n);
	s = (STU*)malloc(n*sizeof(STU));
	if (!s)
		exit(0);
	v = input(s, n);
	printf("原始列表:\n");
	print(v, n);
	sort(v, 0, n - 1);
	printf("排序列表:\n");
	print(v, n);
	free(s);
	system("pause");
	return 0;
MrSunZ 2018-04-29
  • 打赏
  • 举报
回复
看了评论很受益
蓝莓派Alex 2018-04-28
  • 打赏
  • 举报
回复
请帮我看下快排哪里有问题,谢谢。
引用 1 楼 cfjtaishan 的回复:
排序没问题,而是input函数有问题。input的第一个参数,s申请的是一个结构体的空间,但是却被用于于n个结构体空间,所以越界导致程序异常。 改成如下:

    printf("请输入学生人数:\n");
    scanf("%d",&n);
    s = (STU*)malloc(sizeof(STU) * n);
    if (!s)
         exit(0);
    v = input(s,n);
蓝莓派Alex 2018-04-28
  • 打赏
  • 举报
回复
两位再帮我看下这个快速排序哪里出了问题?
会出现断点,而且输出乱码。


#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct MyStruct2
{
int km1, km2, km3;
float aver;
};

struct MyStruct1
{
long num;
char name[20];
struct MyStruct2 exam;
};
typedef struct MyStruct1 STU;
STU *input(STU *, int);
void print(STU *,int);
void sort(STU *,int,int);
int main()
{

int n = 0;
STU *s, *v;
printf("请输入学生人数:\n");
scanf("%d",&n);
s = (STU*)malloc(n*sizeof(STU));
if (!s)
exit(0);
v = input(s,n);
printf("原始列表:\n");
print(v, n);
sort(v,0,n);
printf("排序列表:\n");
print(v,n);
//free(s);
system("pause");
return 0;
}
STU *input(STU *s,int n)
{
int i;
for ( i = 0; i < n; i++)
{
printf("请分别输入学号、姓名、科目1分数、科目2分数、科目3分数(用空格隔开!)\n");
scanf("%ld%s%d%d%d",&s[i].num,&s[i].name,
&s[i].exam.km1,&s[i].exam.km2,&s[i].exam.km3);
s[i].exam.aver = (s[i].exam.km1 + s[i].exam.km2 + s[i].exam.km3) / 3;
}
return s;
}
//结构体排序

/*
void sort(STU *s, int n)
{
STU temp;
int i,j;
for ( i = 0; i <n ; i++)
{
for ( j = 0; j < n-1-i; j++)
{
if (s[j].exam.aver < s[j+1].exam.aver)
{
temp = s[j + 1];
s[j + 1] = s[j];
s[j] = temp;
}
}
}
}
*/
void sort(STU *s, int l,int r)
{
if (l < r)
{
//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
int i = l, j = r;
STU x = s[l];
while (i < j)
{
while (i < j && s[j].exam.aver >= x.exam.aver) // 从右向左找第一个小于x的数
j--;
if (i < j)
s[i++] = s[j];

while (i < j && s[i].exam.aver < x.exam.aver) // 从左向右找第一个大于等于x的数
i++;
if (i < j)
s[j--] = s[i];
}
s[i] = x;
sort(s, l, i - 1); // 递归调用
sort(s, i + 1, r);
}
}


void print(STU *s, int n)
{
int i;

printf("%学号\t姓名\t科目1\t科目2\t科目3\t平均分\n");
for ( i = 0; i < n; i++)
{
printf("%ld\t%s\t%d\t%d\t%d\t%.2f\n",s[i].num, s[i].name,s[i].exam.km1, s[i].exam.km2, s[i].exam.km3,s[i].exam.aver);
}
}
白色一大坨 2018-04-28
  • 打赏
  • 举报
回复
因为分配时候,没有根据学生数量进行分配,已经改好了:

	int n = 0;
	STU *s, *v;
	
	
	printf("请输入学生人数:\n");
	scanf("%d", &n);
	s = (STU*)malloc(sizeof(STU) * n);
	v = input(s, n);
	printf("原始列表:\n");
	print(v, n);
	sort(v, n);
	printf("排序列表:\n");
	print(v, n);
	free(s);
	system("pause");
自信男孩 2018-04-28
  • 打赏
  • 举报
回复
排序没问题,而是input函数有问题。input的第一个参数,s申请的是一个结构体的空间,但是却被用于于n个结构体空间,所以越界导致程序异常。 改成如下:

    printf("请输入学生人数:\n");
    scanf("%d",&n);
    s = (STU*)malloc(sizeof(STU) * n);
    if (!s)
         exit(0);
    v = input(s,n);

69,370

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧