代码之家  ›  专栏  ›  技术社区  ›  f99

需要在内存位置使用指针-bad_alloc返回对象实例的建议吗?

  •  0
  • f99  · 技术社区  · 1 年前

    我在尝试从函数的实例列表中返回实例时遇到了一些问题。

    我有一个集合,用于存储学生类的实例。我试图从“find”函数返回一个实例,以便能够根据学生名称找到这个实例,我正在另一个类/文件中调用这个函数。我希望能够在另一个文件中获得这个对象实例,编辑某些属性,并在实例列表中更新它。

    我在中的查找功能 学生.cpp :

    static set<Student, StudentCmp> studentInstances;
    
    Student* Student::find(int studentId) {
        Student *foundStudent = new Student();
        for (Student s: studentInstances) {
            if(s.getStudentID() == studentId) {
                foundStudent = &s;
            }
        }
        
        return foundStudent;
    }
    

    在另一个类中:

    *Student::find(1).setStudentName("John");
    

    是的,这个学生ID确实存在于列表中,并且在查找功能中一切正常。它会找到ID和相关地址,但当我试图使用find函数给我的地址指向这个变量时,我会得到以下错误:

    Unhandled exception at 0x7622DFD8 in Driver.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x006EF044
    

    我假设这个地址越界了?我不知道为什么,但当我的对象退出函数时,地址似乎不再指向它。我查了一下这个以找到答案,人们说要使用“new”关键字将对象保存在堆中,但这似乎对我不起作用。

    有什么建议可以实现我想要做的事情吗?

    2 回复  |  直到 1 年前
        1
  •  4
  •   NathanOliver    1 年前

    这里的问题是,返回的指针不是指向集合中的对象或分配的指针,而是指向退出函数时被破坏的函数本地对象。

    for (Student s: studentInstances) 
    

    复制每个 Student 在里面 studentInstances .你需要的是一份参考资料

    for (Student& s: studentInstances) 
    

    这样,当您返回一个指针时,您就是在返回一个指向位于中的对象的指针 学生实例


    请注意,如果你找到一个对象,你也会有内存泄漏,因为你从未解除分配 foundStudent 如果你找到一个学生。您的if语句应该是

    if(s.getStudentID() == studentId) {
        delete foundStudent;
        foundStudent = &s;
    }
    

    就我个人而言,我会将函数重构为

    Student* Student::find(int studentId) {
        for (Student& s: studentInstances) {
            if(s.getStudentID() == studentId) {
                return &s;
            }
        }
        return nullptr;
    }
    

    现在,您要么返回一个指向有效对象的指针,要么返回空指针。您可以在呼叫站点轻松检查,并且没有手动内存管理,也没有办法导致泄漏。您只需要确保在调用函数后始终检查空指针结果。

        2
  •  0
  •   MSalters    1 年前

    这个函数有很多错误。其中一部分使用非托管/哑指针,另一部分使用 new .

    也许根本问题在于 Student 物体应该是活的。乍一看,让他们住在里面是有意义的 studentInstances std::set 学生人数。但你正试图改变 大学生 中的对象 std::设置 ,这通常是个坏主意。由于的顺序 std::设置 是由其元素决定的,更改这些元素会破坏集合的顺序,从而破坏整个集合。

    那么,简单的解决方法就是使用一组智能指针。这会解决你的大部分问题——好吧,除了 for (Student s: studentInstances) 。这就构成了 复制 每个学生的。您需要知道在C++中,默认情况下,所有内容都是复制的。