2013-09-17 4 views
0

У меня есть зЬй :: unordered_map как часть глобальной переменной типа структуры:станд :: unordered_map бросать необработанное исключение

typedef struct level_locals_s { 
    std::unordered_map<std::string, std::string> spawnVars; 
    ... 
} level_locals_t; 

level_locals_t level; 


... 

... 


void AddSpawnFields(char *key, char *value) { 
    level.spawnVars.insert(std::make_pair<std::string, std::string>(key, value); 
} 

программа падает на вставке. Я проверил, и ключ/значение верны. Вот где он сбой:

iterator begin() 
{ // return iterator for beginning of mutable sequence 
    return (iterator(this->_Nextnode(this->_Myhead), this)); 
} 

это -> _ Myhead кажется NULL. Что послужило бы причиной этого?

Использование Microsoft Visual C++ 2010. 0xC0000005: Доступ к обнаружению нарушения доступа 0x00000000 является ошибкой.

EDIT: Вот компилируемый пример:

#include <stdio.h> 
#include <string> 
#include <unordered_map> 

using namespace std; 

typedef struct level_locals_s 
{ 
    unordered_map<string, string> spawnArgs; 
} level_locals_t; 

level_locals_t level; 

void main(char **args, int argc) 
{ 
    string st1 = "key"; 
    string st2 = "value"; 

    memset(&level, 0, sizeof(level)); 
    level.spawnArgs.insert(pair<string, string>(st1, st2)); 
} 
+0

'std :: make_pair (..)' лучше использовать 'std :: pair (..) '(если вам нужны явные аргументы шаблона), в противном случае могут возникнуть проблемы с привязкой refval ref. (Как видно в разговоре Стефана Т. Лаваева в Going Native.) ** Примечание: ** Вам даже не нужны явные аргументы шаблона из-за неявных преобразований между типами 'pair'. Это было бы лучшим решением 'std :: make_pair (key, value)'. – dyp

+1

'typedef struct level_locals_s {..} level_locals_t;' Синтаксис C, и ни один из них не нужен и не особенно полезен или симпатичен в C++. В C++ просто используйте 'struct level_locals_t {..};' – dyp

+0

возможно, вам нужно выделить карту – Dru

ответ

5

Именно из-за этой линии

memset(&level, 0, sizeof(level)); 

level_locals_s не тип POD, даже если вы объявляете его С-путь (ЬурейеЕ структуры), поэтому вызов memset на нем приведет к непредвиденным искажениям программы (возможно, это неопределенное поведение?)

В C++ типы не-POD инициализируются c объединяя их конструктор, который будет выполнять все виды инициализации, такие как выделение памяти. Обнуление их не является правильным способом инициализации.

Кажется, что вы исходите из C фона и имеете большое непонимание C++. И, кстати, подпись функции main должна быть int main(int, char **)

+0

+1 Но, может быть, вам стоит упомянуть, что (по умолчанию) ctor вызывается автоматически. – dyp

+0

Спасибо. Я буду использовать конструктор struct вместо этого, чтобы правильно обрабатывать ситуацию, в отличие от memset. – eezstreet

+1

@eezstreet Не требуется явный вызов конструктора или конструктора. Компилятор автоматически генерирует конструктор по умолчанию для вашей 'struct level_locals_s' и вызывает его для глобального' уровня' во время динамической инициализации. Просто оставьте «memset», и он должен работать. – dyp

Смежные вопросы