Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在程序结束时检测到堆栈崩溃_C_Arrays_Struct_Dynamic Memory Allocation - Fatal编程技术网

C 在程序结束时检测到堆栈崩溃

C 在程序结束时检测到堆栈崩溃,c,arrays,struct,dynamic-memory-allocation,C,Arrays,Struct,Dynamic Memory Allocation,当我试图通过返回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 = &

当我试图通过
返回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;
                        }
                }
        }
}
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;
}
valgrind在我尝试退出程序时由于致命错误而终止

它只发生在最后,我可以正确打印结构数组的内容。我已经研究了
realloc()InitArray()中分配内存的方式和我使用realloc()的方式但无效


我做错了什么?

您当前的问题是试图使用“无效指针”。(实际上,这是一个完全有效的指针,它只是指向一个错误的位置)

sStu
是一个
Student
,而
Stu
是指向它的指针。但是,当您添加第二个学生时,您将写入
Stu[1]
——这是
sStu
之后的空格。很可能这个空间中还有其他内容,所以当您向
Stu[1]
写入时,您会覆盖其他内容。(这个空间里到底会有什么是不可预测的。)

看起来你想在你所有的
Stu
地方都使用
ari->Student


(如果这样做,您可能会发现更多的问题-例如,在写入下一个元素后检查是否需要扩展数组)

Valgrind说segfault发生在
AddArray
中的
strcpy
。使用
-g
编译以显示行号。好的,谢谢。我要去试试,我想这是因为我以前的老师教过我这样做。在我看来,我想读起来更清楚。
scanf(“%s”,Stu[Ary->Used].Name)。看起来您正在将单个(堆栈分配)
Student
传递到
Addstudent
中,但随后将其用作
Student
s的数组。
main()
中的
Fin
在使用其值时未初始化。未定义的行为。谢谢,这解决了我问题中的问题,正如你所预测的,还造成了一些问题。谢谢你@Arrowkill不是“造成的”,但可能是“暴露的”。从这个意义上说,你是对的,尽管我的措辞选择不当,但这正是我的意思。
#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;
}
==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