在我的程序中,我读了学生的信息,但是当我输出它时,它会出现乱码,然后出现指针错误。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student{
char *firstName;
char *lastName;
char id[10];
char gender;
int age;
double gpa;
};
void main()
{
int n;
struct student *classroom;
printf("How many students?");
scanf("%d",&n);
classroom = (struct student*) malloc(n*sizeof(struct student));
if (classroom == NULL)
exit(1);
readStudentsInformation(classroom,n);
outputStudents(classroom,n);
printf("The average age is %.2f.\n",averageAge(classroom,n));
printf("The average GPA is %.2f.\n",averageGpa(classroom,n));
sortByLastName(classroom,n);
outputStudents(classroom,n);
sortByID(classroom,n);
outputStudents(classroom,n);
sortByAge(classroom,n);
}
void outputStudents(struct student classroom[], int size)
{
int i;
for (i = 0; i < size; i++)
{
printf("%15s",classroom[i].firstName);
printf("%15s:",classroom[i].lastName);
printf("%14s,",classroom[i].id);
printf("%3c",classroom[i].gender);
printf("%5d",classroom[i].age);
printf("%5.2f",classroom[i].gpa);
}
}
输入: 有多少学生?2 名字?汤姆 姓氏?Arron ID?2 性别?m 年龄?26 GPA?3.9 名字?弗兰克 姓氏?罗伯茨 ID?1 性别?F的 年龄?24 GPA?3.4'
输出:
Roberts Roberts: 2, M 26 3.90 : 1, F 24 3.40The average age is 25.00.
平均GPA为3.65。 检测到 * glibc * ./lab12:munmap_chunk():指针无效:0x00007fff30319a90 *
: 2, M 26 3.90Aborted (core dumped)
完整的代码在这里,但我不想复制200行到堆栈溢出:http://codepad.org/LYpS6t5z
知道会导致什么原因吗?
答案 0 :(得分:1)
这是一个概念上的错误,你可以在几个地方找到它
classroom[i].firstName = (char*)malloc(sizeof(char)*(1+strlen(temp)));
if (classroom[i].firstName == NULL)
exit(1);
classroom[i].firstName = temp;
你想要的是
classroom[i].firstName = (char*)malloc(sizeof(char)*(1+strlen(temp)));
if (classroom[i].firstName == NULL)
exit(1);
strcpy(classroom[i].firstName, temp); // note this
或者,清理了一下:
classroom[i].firstName = malloc(1+strlen(temp)); // note clean up here
if (classroom[i].firstName == NULL)
exit(1);
strcpy(classroom[i].firstName, temp);
甚至只是
classroom[i].firstName = strdup(temp); // this takes place of all the lines above
这些错误解释了为什么你的免费失败。
没有别的事情发生在我身上。
答案 1 :(得分:1)
classroom[i].firstName = (char*)malloc(sizeof(char)*(1+strlen(temp)));
if (classroom[i].firstName == NULL)
exit(1);
classroom[i].firstName = temp;
此处的第二个分配将覆盖地址,泄漏malloc
内存,并在for
迭代完成后立即使指针无效。 lastName
重复使用相同的缓冲区(具有相同的错误),这就是为什么您会看到Roberts Roberts
而不是实际的名字和姓氏。当你去free
时,他们(1)无效,(2)不是malloc
,所以你得到了你看到的崩溃。
就像其他数组一样,你不能通过赋值复制它们,你必须逐字节复制:
size_t len = strlen(temp);
classroom[i].firstName = malloc(1+len);
if (classroom[i].firstName == NULL)
exit(1);
strncpy(classroom[i].firstname, temp, len);
classroom[i].firstname[len] = '\0';
不要投射malloc
的结果。
答案 2 :(得分:1)
在 readStudentsInformation 中发生了奇怪,特别是像
这样的行 classroom[i].lastName = temp;
会导致问题
free(classroom[i].firstName);
下面适当的内存处理:
void readStudentsInformation(struct student classroom[], int size)
{
int i;
char temp[50];
for (i = 0; i < size; i++)
{
printf("First Name?");
scanf("%s",temp);
classroom[i].firstName = (char*)malloc(sizeof(char)*(1+strlen(temp)));
if (classroom[i].firstName == NULL)
exit(1);
/* after mallocing good memory can write in the data.. */
strcpy(classroom[i].firstName, temp);
/* classroom[i].firstName = temp; */
printf("Last Name?");
scanf("%s",temp);
classroom[i].lastName = (char*)malloc(sizeof(char)*(1+strlen(temp)));
if (classroom[i].lastName == NULL)
exit(1);
/* classroom[i].lastName = temp; */
strcpy(classroom[i].lastName, temp);
printf("ID?");
scanf("%s",classroom[i].id);
fflush(stdin);
__fpurge(stdin);
printf("Gender?");
scanf("%c",&classroom[i].gender);
printf("Age?");
scanf("%d",&classroom[i].age);
printf("GPA?");
scanf("%lf",&classroom[i].gpa);
}
}