【问题标题】:User defined linked list returning pointer from function用户定义的链表从函数返回指针
【发布时间】:2013-11-23 15:46:53
【问题描述】:

我知道我不久前问过一个类似的问题,但它仍然不起作用。抱歉重复,我只是不确定为什么它不起作用。我创建了自己的链表(不使用 stl 库)我已经设置了我的类,并且可以按照我想要的方式完美地工作。当我使用函数填充列表时,我遇到的问题是获得参考。 在我的 main 中,我调用了用于填充列表的函数 bookSetUp()。我使这个函数等于一个临时指针。 (这里是代码)
Main.cpp

Book* temp = bookSetUp();
while(temp!=NULL)
{
    cout<<temp->getName()<<endl;
    cout<<temp->getAuthor()<<endl;
    cout<<temp->getISBN()<<endl;
    temp = temp->getNext();
}

bookSetUp() 位于另一个名为 functions.cpp的 .cpp 文件中(链接在两个 .cpp 之间有效,因为我已经对其进行了测试)
functions.cpp强>
Book* bookSetUp()
{

//The items that populate the list
Book a("A Tale of Two Cities", "Charles Dickens", 1203456, true);
Book b("Lord of the rings", "J.R.R Tolkein", 123456, true);
Book c("Le Petit Prince", "Antoine de Saint-Exupéry", 123457, true);
Book d("And Then There Were None", "Agatha Christie", 123458, true);
Book e("Dream of the Red Chamber","Cao Xueqin",123459, true);
Book f("The Hobbit","J.R.R Tolkein",123467, true);

a.setPrev(NULL);
a.setNext(&b);
b.setPrev(&a);
b.setNext(&c);
c.setPrev(&b);
c.setNext(&d);
d.setPrev(&c);
d.setNext(&e);
e.setPrev(&d);
e.setNext(&f);
f.setPrev(&e);
f.setNext(NULL);

Book* temp = &a;
return temp;

}

如您所见,我正在尝试返回指向列表中第一项的指针,以便 main 可以访问它。我的书类具有以下属性:字符串名称、字符串作者、int isbn 和 bool 可用性。
程序崩溃,“bookRepository.exe 中 0x00B16886 处的未处理异常:0xC0000005:访问冲突读取位置 0xCCCCCD04。” 我猜这意味着它没有从 bookSetUp() 函数返回值。
同样在调试器中返回 int ISBN 但不返回字符串或布尔值。
有谁知道为什么这不起作用?如果可以的话,这将是一个巨大的帮助!

【问题讨论】:

    标签: c++ function pointers linked-list


    【解决方案1】:

    对于不太了解指针应该如何使用的新手来说,这是一个很常见的误解。

    一步一个脚印。

    1. 在 bookSetup 中创建 6 个 Book 对象。

    2. 您设置了各种指针,特别是您将temp 设置为a 的地址 书。

    3. 退出函数 bookSetup。

    4. 此时所有 Book 对象都被销毁!

    5. 因此,您从 bookSetup 返回了一个指向已销毁对象的指针。

    6. 因此,当您尝试使用该指针时,您的程序会崩溃。

    此方法无效。您需要了解另一种称为“动态分配”的技术。这使用new 创建书籍。动态创建的对象不会自动销毁,因此对于链表,您确实需要使用动态分配。

    例如

    Book* a = new Book("A Tale of Two Cities", "Charles Dickens", 1203456, true);
    

    【讨论】:

    • 感谢新手 :P 那么我是否必须在主目录中填充一个书单?还是有办法解决这个问题? @约翰
    • @Dennington-bear 刚刚更新了解决这个问题的方法。总之使用new.
    • 是的,我以前见过动态分配,所以它的盛大只是没有意识到它们在函数结束时被破坏了。谢谢
    【解决方案2】:

    是的,我知道。

    在 c++ 中,对象保存在堆中。当函数超出范围时,保存在堆中的变量将被释放(删除)。

    您的程序中的问题是:

    您的 bookSetup 函数正在堆上创建对象 然后它将引用(内存中的地址)返回给这些对象。但是当函数结束时,堆中的所有对象都被删除。因此,您返回一个指向任何内容的地址。

    为了解决这个问题,您需要将这些对象保存在堆栈而不是堆中。

    为此,您使用关键字“new”(“new”关键字在堆栈上分配空间)

    如果我记得这是语法:

    Book* a = new Book("A Tale of Two Cities", "Charles Dickens", 1203456, true);
    Book* b= new Book("Lord of the rings", "J.R.R Tolkein", 123456, true);
    Book* c= new Book("Le Petit Prince", "Antoine de Saint-Exupéry", 123457, true);
    Book* d= new Book("And Then There Were None", "Agatha Christie", 123458, true);
    Book* e= new Book("Dream of the Red Chamber","Cao Xueqin",123459, true);
    Book* f= new Book("The Hobbit","J.R.R Tolkein",123467, true);
    

    【讨论】:

    • 应该是Book* a = new Book(...);
    • 您的回答似乎混淆了“堆”和stack。请解决这个问题!
    猜你喜欢
    • 2011-12-06
    • 2018-07-03
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 2019-09-11
    • 2010-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多