在程序结束时检测到堆栈崩溃 [英] Stack Smashing Detected at End of Program

查看:214
本文介绍了在程序结束时检测到堆栈崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在以较小的规模测试程序,以区分试图在主功能末尾通过 return 0; 退出程序时遇到的问题。

I am currently testing a program on a smaller scale to distinguish a problem when I attempt to exit the program by return 0; at the end of the main function.

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;
                        }
                }
        }
}

标题.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;
}

在文件末尾,当我尝试返回0; 我收到此错误:

At the end of the file, when I try to return 0; I get this error:


*检测到堆栈粉碎* :./a.out已终止
分段错误(核心已转储)

* stack smashing detected *: ./a.out terminated Segmentation fault (core dumped)

当我使用valgrind时,得到以下输出:

When I use valgrind, I get this output:

==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终止。

valgrind terminates due to an fatal error during my attempt to exit my program.

它只发生在最后,我可以正确打印struct数组的内容。我已经研究了 realloc(); ,因为我确信错误在于此,但是我不确定我做错了什么。我试图改变我在 InitArray(); 中分配内存的方式以及我使用 realloc(); 但无济于事。

It only happens at the end and I can print the contents of the struct array properly. I have looked into realloc(); since I am fairly sure the error lies within that, however I am uncertain precisely what I have done wrong. I have attempted to alter the way I allocate the memory in InitArray(); and the way I use realloc(); but to no avail.

我做错了什么?

推荐答案

您的直接问题是您正在尝试使用无效的指针。 (实际上,它是一个完全有效的指针,只是指向错误的位置)

Your immediate problem is that you're trying to use an "invalid pointer". (Actually, it's a completely valid pointer, it just points to a wrong place)

sStu Student Stu 是指向它的指针。但是,当您添加第二个学生时,您将写入 Stu [1] -这是 sStu 之后的空格。此空间中很可能还有其他内容,因此当您写入 Stu [1] 时,您将覆盖其他内容。 (在那个空间中 会是完全不可预测的。)

sStu is a Student, and Stu is a pointer to it. But when you add your second student, you write to Stu[1] - which is the space after sStu. Most likely there's something else in this space, so when you write to Stu[1], you overwrite something else. (It's unpredictable exactly what will be in that space.)

似乎您要使用 Ary-> ;学生到处都有 Stu

It looks like you want to use Ary->Student everywhere you have Stu.

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

(If you do that, you might find some more problems - such as the fact that you check if you need to expand the array after writing to the next element)

这篇关于在程序结束时检测到堆栈崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆