在程序结束时检测到堆栈崩溃
Stack Smashing Detected at End of Program
我目前正在小规模测试一个程序,以区分当我试图在 main 函数结束时通过 return 0;
退出程序时出现的问题。
Main.c
#include <stdio.h>
#include <stdlib.h>
#include "Header.h"
int main (void)
{
int i;
int Fin = 0;
Student sStu;
Array aAry;
Student *Stu = &sStu;
Array *Ary = &aAry;
InitArray(Ary, 1);
while(Fin != 2)
{
printf("Please choose a selection.\n");
printf("1. Add Student\n");
printf("2. Print Students\n");
printf("3. Exit\n");
scanf("%d", &i);
switch(i)
{
case 1:
{
AddStudent(Stu, Ary);
break;
}
case 2:
{
for(i = 0; i < Ary->Size; i++)
{
printf("%s %d\n", Stu[i].Name, Stu[i].IDn);
}
break;
}
case 3:
{
return 0;
}
}
}
}
Header.h
#ifndef HEADER_H_
#define HEADER_H_
typedef struct student
{
char Name[30];
int IDn;
}Student;
typedef struct array
{
Student *Student;
size_t Used;
size_t Size;
}Array;
void InitArray(Array *Ary, int InitSize);
void AddArray(Array *Ary);
Student AddStudent(Student *Stu, Array *Ary);
#endif
Grade.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Header.h"
void InitArray(Array *Ary, int InitSize)
{
Ary->Student = malloc(InitSize * sizeof(Student));
Ary->Used = 0;
Ary->Size = InitSize;
memset(&Ary->Student[0], 0 , sizeof(Student) * InitSize);
}
void AddArray(Array *Ary)
{
Student Stud;
if(Ary->Used == Ary->Size)
{
Ary->Size *= 2;
Ary->Student = realloc(Ary->Student, Ary->Size * sizeof(Student));
}
strcpy(Ary->Student[Ary->Used].Name, Stud.Name);
Ary->Student[Ary->Used].IDn = Stud.IDn;
Ary->Used++;
}
Student AddStudent(Student *Stu, Array *Ary)
{
int i;
printf("\nStudent ID numbers cannot be the same!\n");
printf("Please enter the student's name: ");
scanf("%s", Stu[Ary->Used].Name);
printf("Please enter the student's ID Number: ");
scanf("%d", &Stu[Ary->Used].IDn);
AddArray(Ary);
printf("\n");
return;
}
在文件末尾,当我尝试 return 0;
时出现此错误:
* stack smashing detected *: ./a.out terminated
Segmentation fault (core dumped)
当我使用 valgrind 时,我得到这个输出:
==9966== Invalid write of size 1
==9966== at 0x402C6C3: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==9966== by 0x8048687: AddArray (in /home/ctj0033/CSCE_1040/Homework/2_Homework/2_Test/a.out)
==9966== by 0x804874B: AddStudent (in /home/ctj0033/CSCE_1040/Homework/2_Homework/2_Test/a.out)
==9966== by 0x804881C: main (in /home/ctj0033/CSCE_1040/Homework/2_Homework/2_Test/a.out)
==9966== Address 0x41f804c is 0 bytes after a block of size 36 alloc'd
valgrind 在我尝试退出程序时由于致命错误而终止。
它只发生在最后,我可以正确打印结构数组的内容。我已经调查了 realloc();
因为我相当确定错误就在其中,但是我不确定我到底做错了什么。我试图改变我在 InitArray();
中分配内存的方式和我使用 realloc();
的方式但无济于事。
我做错了什么?
您的直接问题是您正在尝试使用 "invalid pointer"。 (实际上,它是一个完全有效的指针,它只是指向了一个错误的地方)
sStu
是一个 Student
,Stu
是指向它的指针。但是当你添加你的第二个学生时,你写到 Stu[1]
- 这是 sStu
之后的 space。此 space 中很可能还有其他内容,因此当您写入 Stu[1]
时,您会覆盖其他内容。 (无法预测 会在 space 中。)
看起来你想在所有有 Stu
.
的地方使用 Ary->Student
(如果这样做,您可能会发现更多问题 - 例如您检查是否需要在 写入下一个元素后 扩展数组)
我目前正在小规模测试一个程序,以区分当我试图在 main 函数结束时通过 return 0;
退出程序时出现的问题。
Main.c
#include <stdio.h>
#include <stdlib.h>
#include "Header.h"
int main (void)
{
int i;
int Fin = 0;
Student sStu;
Array aAry;
Student *Stu = &sStu;
Array *Ary = &aAry;
InitArray(Ary, 1);
while(Fin != 2)
{
printf("Please choose a selection.\n");
printf("1. Add Student\n");
printf("2. Print Students\n");
printf("3. Exit\n");
scanf("%d", &i);
switch(i)
{
case 1:
{
AddStudent(Stu, Ary);
break;
}
case 2:
{
for(i = 0; i < Ary->Size; i++)
{
printf("%s %d\n", Stu[i].Name, Stu[i].IDn);
}
break;
}
case 3:
{
return 0;
}
}
}
}
Header.h
#ifndef HEADER_H_
#define HEADER_H_
typedef struct student
{
char Name[30];
int IDn;
}Student;
typedef struct array
{
Student *Student;
size_t Used;
size_t Size;
}Array;
void InitArray(Array *Ary, int InitSize);
void AddArray(Array *Ary);
Student AddStudent(Student *Stu, Array *Ary);
#endif
Grade.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Header.h"
void InitArray(Array *Ary, int InitSize)
{
Ary->Student = malloc(InitSize * sizeof(Student));
Ary->Used = 0;
Ary->Size = InitSize;
memset(&Ary->Student[0], 0 , sizeof(Student) * InitSize);
}
void AddArray(Array *Ary)
{
Student Stud;
if(Ary->Used == Ary->Size)
{
Ary->Size *= 2;
Ary->Student = realloc(Ary->Student, Ary->Size * sizeof(Student));
}
strcpy(Ary->Student[Ary->Used].Name, Stud.Name);
Ary->Student[Ary->Used].IDn = Stud.IDn;
Ary->Used++;
}
Student AddStudent(Student *Stu, Array *Ary)
{
int i;
printf("\nStudent ID numbers cannot be the same!\n");
printf("Please enter the student's name: ");
scanf("%s", Stu[Ary->Used].Name);
printf("Please enter the student's ID Number: ");
scanf("%d", &Stu[Ary->Used].IDn);
AddArray(Ary);
printf("\n");
return;
}
在文件末尾,当我尝试 return 0;
时出现此错误:
* stack smashing detected *: ./a.out terminated Segmentation fault (core dumped)
当我使用 valgrind 时,我得到这个输出:
==9966== Invalid write of size 1
==9966== at 0x402C6C3: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==9966== by 0x8048687: AddArray (in /home/ctj0033/CSCE_1040/Homework/2_Homework/2_Test/a.out)
==9966== by 0x804874B: AddStudent (in /home/ctj0033/CSCE_1040/Homework/2_Homework/2_Test/a.out)
==9966== by 0x804881C: main (in /home/ctj0033/CSCE_1040/Homework/2_Homework/2_Test/a.out)
==9966== Address 0x41f804c is 0 bytes after a block of size 36 alloc'd
valgrind 在我尝试退出程序时由于致命错误而终止。
它只发生在最后,我可以正确打印结构数组的内容。我已经调查了 realloc();
因为我相当确定错误就在其中,但是我不确定我到底做错了什么。我试图改变我在 InitArray();
中分配内存的方式和我使用 realloc();
的方式但无济于事。
我做错了什么?
您的直接问题是您正在尝试使用 "invalid pointer"。 (实际上,它是一个完全有效的指针,它只是指向了一个错误的地方)
sStu
是一个 Student
,Stu
是指向它的指针。但是当你添加你的第二个学生时,你写到 Stu[1]
- 这是 sStu
之后的 space。此 space 中很可能还有其他内容,因此当您写入 Stu[1]
时,您会覆盖其他内容。 (无法预测 会在 space 中。)
看起来你想在所有有 Stu
.
Ary->Student
(如果这样做,您可能会发现更多问题 - 例如您检查是否需要在 写入下一个元素后 扩展数组)