通过函数 C++ 创建结构数组

Create struct array by a function C++

我想创建一个创建结构数组的函数。我所做的如下:

struct Student {
    char studentNames[128]; 
    unsigned int FN; 
    short selectiveDisciplinesList[10]; 
    unsigned short countOfSelectiveDisciplines; 
    bool hasTakenExams;
};
    
void fillInStudentInfo(Student &student) {...}

Student createStudentsArray() {
    unsigned int countOfStudents;
    std::cout << "Enter the number of students You are going to write down: " << std::endl;
    std::cin >> countOfStudents;
    Student studentsArray[countOfStudents];

    for (int i = 0; i < countOfStudents; ++i) {
        fillInStudentInfo(studentsArray[i]);
    }

    return *studentsArray;
}

然而,当在 main() 时,我分配:

Student studentArray = createStudentsArray();

我无法访问每个不同结构的成员 (f.e。studentArray[i].something)。

问题出在哪里?

如果我这样做:

Student * createStudentsArray() {
    ...
    return studentsArray;
}

Student * studentArray = createStudentsArray();

我的 IDE 警告我:

Address of stack memory associated with local variable returned

但我似乎确实能够访问每个结构的成员。这是一件坏事吗?

你真的不能用那种方式做你想做的事:

Student createStudentsArray() {
    ...
    Student studentsArray[countOfStudents];
    ...
    return *studentsArray;
}

首先,这是使用变长数组,严格来说是invalid C++。例如,我的编译器不允许它。

其次,它只会return一个Student。即使它 return 全部编辑了它们,它的效率也非常低,因为它必须将它们全部复制,但它没有。

你试过这个:

Student *createStudentsArray() {
    ...
    Student studentsArray[countOfStudents];
    ...
    return studentsArray;
}

这更糟。一旦函数结束,分配给该数组的内存就会被释放。这就是编译器警告您的内容。事后似乎一切正常,但非常糟糕的事情(tm) 很快就会发生。

最有经验的 C++ 开发人员会这样做:

std::vector<Student> createStudentsArray() {
    ...
    std::vector<Student> students(countOfStudents);
    ...
    return students;
}

如果您“不被允许使用矢量”(Whosebug 一直都能看到),那么请执行:

Student *createStudentsArray() {
    ...
    Student *studentsArray = new Student[countOfStudents];
    ...
    return studentsArray;
}

但是您必须 delete[] 使用完该数组。

脚注 - 如需额外信息,如果您真的感兴趣的话。

事实上,有经验的开发者会这样做:

std::vector<std::shared_ptr<Student>> createStudentsArray() {
    ...
    std::vector<std::shared_ptr<Student> students(countOfStudents);
    for (int......)
    {
        students.push_back(std::make_shared<Student>());
        ...
    }
    return students;
}

现在,vector 包含一堆智能指针而不是实际对象,这是制作大型对象数组(或其他容器)的最有效方法。 std::vectorstd::shared_ptr 将自动为您清理所有内存。