分配指针数组的分段错误?

时间:2016-05-20 07:01:02

标签: c++ function pointers struct segmentation-fault

我花了几个小时试图弄清楚为什么我会遇到一个段错误。我的代码运行正常,因为我的nameList指针数组是用我输入的名称初始化的。但是,当我将nameList传递给我的函数时,在createStudentList函数中为每个名称动态分配适当的空间量。如果您有任何想法,请通知我一个解释,我不是只想找到答案来解决它。谢谢。 (这是一个赋值,因此需要遵循一些指导原则[例如使用char数组而不是字符串]。)

这是我的代码:

#include "main.h"
using namespace std;

const int MAXCHAR = 101;

struct Student
{
    char *name;
    double gpa;
};

Student ** createStudentList(char ** names, int size);

int main()
{
    int size = 0;
    char temp[MAXCHAR];
    char **nameList = nullptr;
    Student **studentList = nullptr;

    cout << "Enter amount of names: ";
    cin >> size;
    cout << endl;
    cin.clear();
    cin.ignore(10, '\n');
    nameList = new char *[size];

    for(auto i = 0; i < size; i++)
    {   
        cout << "Enter name: ";
        cin.get(temp, MAXCHAR, '\n');
        cout << endl;
        cin.ignore(10, '\n');
        nameList[i] = new char[strlen(temp) + 1]; 
        strcpy(nameList[i], temp);
    }   

    studentList = createStudentList(nameList, size);

    return 0;
}

Student ** createStudentList(char ** names, int size)
{
    Student **tempStudentList = nullptr;
    tempStudentList = new Student *[size];


    for(auto idx = 0; idx < size; idx++)
    {
        tempStudentList[idx]->name = new char[strlen(names[idx]) + 1];
        strcpy(tempStudentList[idx]->name, names[idx]);
        tempStudentList[idx]->gpa = 0;
    }
    return tempStudentList;
}

2 个答案:

答案 0 :(得分:2)

您没有在循环中分配Student个实例。试试这个:

for(auto idx = 0; idx < size; idx++)
{
    tempStudentList[idx] = new Student;

    tempStudentList[idx]->name = new char[strlen(names[idx]) + 1];
    strcpy(tempStudentList[idx]->name, names[idx]);
    tempStudentList[idx]->gpa = 0;
}

另外,正如评论中所指出的,这不是现代的C ++。您最好使用std::stringstd::vector。例如,将Student更改为:

struct Student
{
    std::string name;
    double gpa;
};

std::vector中添加使用createStudentList

std::vector<Student> createStudentList(const std::vector<string> &names)
{
    std::vector<Student> students;    

    for(auto idx = 0; idx < names.size(); idx++)
    {
        Student student;
        student.name = names[index];
        student.gpa = 0

        students.push_back(student);
    }

    return students;
}

这将节省您必须分配原始内存,否则您将需要删除。

答案 1 :(得分:2)

分段错误的原因:

for(auto idx = 0; idx < size; idx++)
{
    // tempStudentList[idx] is `Student *` and you don't allocate memory for it
    // this is UB
    tempStudentList[idx]->name = new char[strlen(names[idx]) + 1];
    strcpy(tempStudentList[idx]->name, names[idx]);
    tempStudentList[idx]->gpa = 0;
}

但是,tempStudentList根本不需要Student**Student*就足够了。

Student * createStudentList(char ** names, int size)
{
    Student *tempStudentList = new Student[size];
    for(auto idx = 0; idx < size; idx++)
    {
        tempStudentList[idx].name = new char[strlen(names[idx]) + 1];
        strcpy(tempStudentList[idx].name, names[idx]);
        tempStudentList[idx].gpa = 0;
    }
    return tempStudentList;
}

顺便说一句:您需要delete多个内容,nameListnameList的元素,studentListname Student,以及等等。这就是我们应该使用STL的原因。