崩溃 - 添加到地图并设置STL - c ++

时间:2010-03-02 06:13:00

标签: c++

我有一张CD,DVD。预订媒体节目。目前,我正在尝试将书籍信息添加到一组。我得到了一个令人讨厌的崩溃。

错误:a04xc.exe中0x00449d76处的未处理异常:0xC0000005:访问冲突读取位置0x00000014。

所以,显然它试图访问内存而不是假设?只是不确定为什么或我需要做什么来添加信息?

它来自这个功能......

const Item* Library::addBook(const string& title, const string& author, const int nPages)
{

Book* item = new Book(title,author,nPages);
allBooks.insert(item); // add to set of all books
allBooksByAuthor[author]->insert(item);  // causing error..
return item;

}

这是司机..

// add items to library
cout << ">>> adding items to library:\n\n";
item = library->addBook("The Curious Incident of the Dog in the Night-Time", "Mark Haddon", 240);
if (item != NULL) {
    library->addKeywordForItem(item, "autism");
    library->addKeywordForItem(item, "Asperger's Syndrome");
    library->printItem(cout, item);
    }

这里是库cpp的一部分,我遇到了addbooks功能

的问题
#include "Library.h"
#include "book.h"



ItemSet allBooks;                // for my sets defined in the Items cpp
ItemSetMap allBooksByAuthor;


void Library::addKeywordForItem(const Item* item, const string& keyword)
{

//item->addKeyword(keyword);

}

const ItemSet* Library::itemsForKeyword(const string& keyword) const
{
return NULL;
}

void Library::printItem(ostream& out, const Item* const item) const
{
}

// book-related functions

const Item* Library::addBook(const string& title, const string& author, const int nPages)
{

Book* item = new Book(title,author,nPages);
allBooks.insert(item); // add to set of all books
allBooksByAuthor[author]->insert(item);  // add to set of books by this author
return item;

}

这是项目类

#pragma once

#include <ostream>
#include <map>
#include <set>
#include <string>
#include "Item.h"

using namespace std;

typedef set<Item*>              ItemSet;
typedef map<string,Item*>       ItemMap;
typedef map<string,ItemSet*>    ItemSetMap;

class Library
{

public:
// general functions

void addKeywordForItem(const Item* const item, const string& keyword);
const ItemSet* itemsForKeyword(const string& keyword) const;
void printItem(ostream& out, const Item* const item) const;

// book-related functions

const Item* addBook(const string& title, const string& author, int const nPages);
const ItemSet* booksByAuthor(const string& author) const;
const ItemSet* books() const;

// music-related functions

const Item* addMusicCD(const string& title, const string& band, const int nSongs);
void addBandMember(const Item* const musicCD, const string& member);
const ItemSet* musicByBand(const string& band) const;
const ItemSet* musicByMusician(const string& musician) const;
const ItemSet* musicCDs() const;

// movie-related functions

const Item* addMovieDVD(const string& title, const string& director, const int nScenes);
void addCastMember(const Item* const movie, const string& member);
const ItemSet* moviesByDirector(const string& director) const;
const ItemSet* moviesByActor(const string& actor) const;
const ItemSet* movies() const;
};

这是book.h

#ifndef BOOK_H
#define BOOK_H

#pragma once
#include "item.h"

using namespace std;

class Book : public Item
{
public:
Book(const string& title, const string& author, const int nPages);
~Book();
const int getPages() const;
const string getAuthor() const;
virtual void print(ostream& out) const;

private:

int numPages;
string Author;

};
ostream& operator<<(ostream& out, const Book* book);
#endif

我正在学习STL,我很难学习这里发生的事情。 我明白了。我只是不确定在我的情况图中是为了什么?它是否向作者添加项目?他们将它们都添加到ItemSetMap?

typedef set<Item*>                ItemSet;
typedef map<string,Item*>         ItemMap;
typedef map<string,ItemSet*>      ItemSetMap;

所以,我该如何解决这次崩溃?我没有正确地将作者添加到项目中吗?

谢谢..

3 个答案:

答案 0 :(得分:5)

我相信typedef map<string,ItemSet*> ItemSetMap;应为typedef map<string, ItemSet> ItemSetMap;

allBooksByAuthor[author]当前返回一个ItemSet指针,但你真的想要取消引用一个ItemSet,你可以通过上面提到的typedef更改,并将你的错误行更改为:

allBooksByAuthor[author].insert(item);

答案 1 :(得分:1)

Library::addBook()中:当您访问allBooksByAuthor[author]时,请检查author是否确实在地图中。 operator[]() std::map<K,V>返回对您正在搜索的键值的引用,但如果该键不在映射中,则会为该键创建一个条目,然后返回该键值的引用

在您的代码中,如果映射中不存在键author,则映射将为该键创建一个新条目,其值(类型为ItemSet*)默认初始化。现在,当您收到对未初始化指针的引用然后尝试取消引用它时,结果行为是未定义的。

答案 2 :(得分:0)

正如JonM所说,正确的答案是将地图更改为包含设置对象而不是指针。

但是,如果您受限于存储指针,则需要在需要时手动创建新集。对于新作者,使用allBooksByAuthor[author]将插入带有空指针的新条目,您不能解除引用。在这种情况下,您需要创建一个新集并更新地图中的指针。您还可以查看allBooksByAuthor.find(author),它对新作者有不同的行为。

然后,您需要确保在从地图中删除这些集时删除它们,并在删除地图时删除任何剩余的集,否则分配给它们的内存将永远丢失。这种资源泄漏是你永远不应该处理像这样的原始指针的一个原因;在地图中存储对象将完全为您处理内存管理。

由于这是作业,我不会给你任何代码 - 这应该足以让你开始。