2013-11-22 4 views
0

Я получаю ошибку сегментации, когда пытаюсь вставить ее в свою карту.C++ - std :: map.insert() segmentation fault

функция выглядит примерно так:

void add(std::string id, std::string name) 
{ 
Asset asset(nullptr, false, name); 
mAssets.insert(std::make_pair<std::string, Asset>(id,asset)); <-- This line gives segfault 
} 

mAssets просто объявленную

std::map<assetID, Asset> mAssets; 

А класс активов (коряво) объявлен как это:

class Asset 
{ 
public: 
    Asset(T* a, bool l, std::string f) : asset(a), loaded(l), filename(f) 
    { 
    } 
    Asset(const Asset& copy) 
{ 
    loaded = copy.loaded; 
    filename = copy.filename; 
    asset = new T(); 
    *asset = *copy.asset; 
} 
    ~Asset() 
{ 
    delete asset; 
} 
    Asset& operator=(const Asset& other) 
{ 
    Asset temp(other); 
    loaded = temp.loaded; 
    filename = temp.filename; 
    std::swap(asset,temp.asset); 
    return *this; 
} 

    T*   asset; 
    bool  loaded; 
    std::string filename; 
}; 
+0

Что вы AssetID ключ класса? –

+0

propertyID is typedeffed std :: string – Henningsson

+0

Как правило, чтобы сделать код более удобочитаемым (для меня, по крайней мере), я предпочитаю: 'mAssets [id] = asset;' – crashmstr

ответ

4

Ваша проблема находится здесь в вашем экземпляре копии:

asset = new T(); 
    *asset = *copy.asset; 

Я оставлю вас, чтобы понять, почему ...

+0

исправление ошибки разыменования все еще не исправляет сбой – Henningsson

+0

, тогда ваша проблема находится в другом месте (по крайней мере, не в коде, который вы положили ...) – Nim

+0

Я сузил его до этой конкретной строки, код, похоже, работает на моем ноутбуке запустив ubuntu, но не на этом компьютере Solaris. – Henningsson

1

На ваш конструктор копирования вы derefferencing нулевой указатель:

*asset = *copy.asset 

из

Asset asset(nullptr, false, name); 

Проверьте ваш указатели указателей и избегать разыменования нулевых указателей:

Asset(const Asset& copy) 
{ 
    loaded = copy.loaded; 
    filename = copy.filename; 
    if (copy.asset) 
    { 
     asset = new T(); // better may be asset = new T(copy) 
     *asset = *copy.asset; 
    } 
    else 
    { 
     asset = nullptr 
    } 
} 
+0

Что еще не исправляет сбой – Henningsson

+0

Вы пытались проверить удаление указателя при уничтожении? ??? На некоторых платформах, таких как Linux и большинство unix, вы не можете удалить нулевой указатель. Просмотрите все ваши указатели разыгрывания –

+0

исправил это, еще не повезло. im running solaris btw – Henningsson

0

* asset = * copy.asset; // вы должны проверить, является ли NULL актив или нет, то проверьте актив

Это как ваш код будет работать:

#include <iostream> 
#include <map> 

using namespace std; 

template<class T> 
class Asset 
{ 
    public: 
    Asset(T* a, bool l, std::string f) : asset(a), loaded(l), filename(f) 
    { 
    } 
    Asset(const Asset& copy) 
    { 
     cout<<"copy"<<endl; 
     loaded = copy.loaded; 
     filename = copy.filename; 
     asset = new T(); 
     if(&copy != NULL) 
     { 
     if(copy.asset != NULL) 
     *asset = *(copy.asset); 
     } 
    } 
    ~Asset() 
    { 
     delete asset; 
    } 
    Asset& operator=(const Asset& other) 
    { 
     Asset temp(other); 
     loaded = temp.loaded; 
     filename = temp.filename; 
     std::swap(asset,temp.asset); 
     return *this; 
    } 

    T*   asset; 
    bool  loaded; 
    std::string filename; 
}; 

std::map <string,Asset<int> > mAssets; 

void add(std::string id, std::string name) 
{ 
    Asset<int> asset(NULL, false, name); 
    mAssets.insert(std::make_pair<std::string, Asset<int> >(id,asset)); //<-- This line gives segfault 
} 


int main() 
{ 
    add("1","hi"); 
    cout<<"run"<<endl; 

} 
+0

Какова цель этого -> ' if (& copy! = NULL) ' – Nim

+0

, если (& copy! = NULL) можно удалить, но перед копированием указателей данных следует проверить, указали ли они действительные данные для обеспечения работы конструктора копирования. – Nik