首页 文章

如何动态分配涉及指针的结构?

提问于
浏览
0

我正在使用包含三个字段的学生结构 . 然后我在main中声明了一个指向Student结构的指针 . 然后我将该指针传递给一个函数 . 此函数计算文件中的行数,然后动态分配Student数组,使其与文件中的行数相同,然后将数据读入数组 . 我坚持动态分配Student数组,因为函数参数涉及到结构的指针 .

因为函数参数是一个指向结构的指针,如果我做 pointer = new Student[record]; 会有效吗?我不知道你是否会将Student数组动态分配到与文件中行数相同的大小 . 函数参数中的指针让我很困惑 .

struct Student
{
string name;
double gpa[NUM_OF_QUARTERS];
double average;
};

bool fillArr(Student* pointer);

int main()
{

Student* ptr;

if (!fillArr(ptr))
    return 1;

return 0;
}

bool fillArr(Student* pointer)
{

ifstream infile;
infile.open("student_records.txt");
if (!infile)
{
    cout << "Error opening file\n";
    return false;
}   
int record = 0;
string str;
while(getline(infile, str))
    ++record;
cout << "number of lines in the file " << record << endl;
infile.clear();
infile.seekg(0, ios::beg);

pointer = new Student[record];  // Is this how you would dynamically allocate the Student array?
// after dynamically allocating Student array, read in the data from the file
}

2 回答

  • 3

    你的方法部分可行,但我宁愿使用 std::vector<Student> . 如果你想要真正的花哨,你可以使用 std::vector::emplace_back() 函数来避免首先构造 Student 的开销,然后用 std::vector::push_back() 将其复制到 std::vector . 你可以找到一个非常好的描述和示例here,它使用类型 President 而不是 Student .

    如果要在 main() 中使用新创建的数组,则签名应为 bool fillArr(Student *&pointer) .

    如果将 ptr 变量"by-value"传递给 fillArr()main() 中的 ptr 将不会更改,因为 fillArr() 中的 pointer 在函数调用时包含 ptr 的值 . 这与函数签名一起发生

    bool fillArr(Student *pointer)
    

    如果您改为传递它"by-reference", fillArr() 中的 pointer 将引用您在 main() 中传递的变量 . 这与建议的函数签名一起发生

    bool fillArr(Student *&pointer)
    
  • 1

    您在这里的方法将无法正常工作,因为您按值传递指针 . 如果要以此方式继续,请更改函数,使其通过引用获取指针:

    bool fillArr(Student*& ptr) {
       ...
    }
    

    如果你不这样做,那么你只是改变原始指针的副本指向的位置,而不是原始指针本身指向的位置 .

    也就是说,我认为通过不使用 std::vector 代替动态分配的数组,你所做的事情比他们需要的要困难得多 . 使用 std::vector 可以轻松实现:

    std::vector<Student> fillArr() {
        ifstream infile("student_records.txt");
        if (!infile) {
          /* error handling */
        }
    
        std::vector<Student> result;
        for (string line; getline(infile, line); ) {
             Student curr = /* initialize curr based on line */
             result.push_back(curr);
        }
        return result;
    }
    

    这避免了原始指针,只读取文件一次,不会冒被提供指针为空的风险,并且不需要显式内存管理 . 这更像是做事的C方式,所以我强烈推荐它!

相关问题