gpt4 book ai didi

c - 出现 fatal error 代码 - 堆损坏

转载 作者:行者123 更新时间:2023-11-30 16:19:52 24 4
gpt4 key购买 nike

来自外部编译器的新图片..退出代码可以吗?

enter image description here

这是完整的代码。在将所需的输出打印到屏幕上后,我遇到了一个问题程序消失了。我想这是我为结构数组分配内存的方式以及 for 循环中每个结构的 .name 字段的问题。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

#define MAX_NAME_LEN 50

typedef struct stud
{
char *name;
int marks[4];
float avg;
}student;


student* Create_Class(int);
void Avg_Mark(student*);
void Print_One(student*);
void printExcellent(student*);

void main()
{
int size, i;
student *arr, *newArr;
printf("\nEnter the number of students: ");
scanf_s("%d", &size);
newArr = Create_Class(&size);
for (i = 0; i < size; i++)
{
printExcellent(newArr+i);
}
for (i=0;i<size;i++) free(newArr[i].name);
free(newArr);
_getch();
}

student* Create_Class(int size)
{
student *p;
char str[MAX_NAME_LEN];
int i, j;
p = (student*)calloc(size , sizeof(student));
if (!p)
{
printf("Memory allocation failure.");
exit(1);
}

for (i = 0; i < size; i++)
{
printf("Enter your name: ");
rewind(stdin);
gets(str);
p[i].name = (char*)calloc(strlen(str)+1,sizeof(char));
if (!(p[i].name))
{
printf("Memory allocation error!");
exit(1);
}
strcpy_s(p[i].name,50,str);
printf("Enter your marks: ");
for (j = 0; j < 4; j++)
{
scanf_s("%d", &p[i].marks[j]);
}
Avg_Mark(p + i);
}
return p;
}


void Avg_Mark(student* s)
{
int i, sum=0;
for (i = 0; i < 4; i++)
sum += s->marks[i];
s->avg = (float)sum / 4;
}


void Print_One(student* s)
{
printf("The average of %s is %.1f\n", s->name, s->avg);
}

void printExcellent(student* s)
{
if ((s->avg) > 85)
Print_One(s);
}

最佳答案

我会向你指出我发现的所有可疑之处:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

#define MAX_NAME_LEN 50

typedef struct stud
{
char *name;
int marks[4];
float avg;
}student;


student* Create_Class(int);
void Avg_Mark(student*);
void Print_One(student*);
void printExcellent(student*);

void main()
{
int size, i;
student *arr, *newArr;
printf("\nEnter the number of students: ");
scanf_s("%d", &size);

// This is wrong. Remove the &...
newArr = Create_Class(&size);

for (i = 0; i < size; i++)
{
printExcellent(newArr+i);
}
for (i=0;i<size;i++) free(newArr[i].name);
free(newArr);
_getch();
}

student* Create_Class(int size)
{
student *p;
char str[MAX_NAME_LEN];
int i, j;

// Consider checking size for a sane value.

// Ok, allocate an array of students.
p = (student*)calloc(size , sizeof(student));
if (!p)
{
printf("Memory allocation failure.");
exit(1);
}

for (i = 0; i < size; i++)
{
printf("Enter your name: ");

// These 2 lines scare the heck out of me. I'd really do this differently.
// gets is the devil and the see:
// https://stackoverflow.com/questions/20052657/reversing-stdin-in-c
// for why this may not work well.

rewind(stdin);
gets(str);

// What if str is not a terminated string? Then 1 char of 0? Guess this is ok. Hope it doesn't overflow on the copy below though (consider fixed max size and not using a temporary)
p[i].name = (char*)calloc(strlen(str)+1,sizeof(char));
if (!(p[i].name))
{
printf("Memory allocation error!");
exit(1);
}
// Do a fast copy of up to 50 chars. I'd really want to verify this output to be sure it works.
strcpy_s(p[i].name,50,str);
printf("Enter your marks: ");
for (j = 0; j < 4; j++)
{
// Hope this inputs the way you want.
scanf_s("%d", &p[i].marks[j]);
}

// This should work, but I prefer more explicit pointers.
Avg_Mark(p + i);
}

return p;
}


void Avg_Mark(student* s)
{
// What if s is Null?

int i, sum=0;

// 4 is a magic number. Make this a constant.
for (i = 0; i < 4; i++)
sum += s->marks[i];

// This won't be as accurate as you want. Consider an integer solution.
s->avg = (float)sum / 4;
}


void Print_One(student* s)
{
// What if s is Null? What about s->name?
printf("The average of %s is %.1f\n", s->name, s->avg);
}

void printExcellent(student* s)
{
// What if s is Null?
if ((s->avg) > 85)
Print_One(s);
}

注意:在查看这段代码时,除了大​​小上的 & 以及可能的获取/倒带调用之外,我没有看到任何“危险信号”。我仍然会向您的函数添加空断言,并使用调试器遍历它,以确保一切都符合您的预期。老实说,这里发生的事情已经够多了,我更喜欢调试器的帮助,而不是在我编写注释时快速跟踪代码。

<小时/>

更新

如果我将您所有的 scanf_s 更改为 scanf() 调用,请将您的 gets()/rewind() 调用替换为简单的 scanf("%s", str) 调用,并将时髦的 strcpy_s() 函数更改为更简单的 strcpy()strncpy () 调用,你的程序对我来说似乎没有崩溃。我的观点是,strcpy_s() 调用在执行“快速”复制时会损坏 RAM。

关于c - 出现 fatal error 代码 - 堆损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55465268/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com