Удаление std :: map (Visual C ++) - PullRequest
4 голосов
/ 01 марта 2010

У меня есть указатель на карту, которую я пытаюсь удалить (эта карта была назначена новой).

Эта карта действительна, я думаю, когда я нахожу ее во время отладки, она показывает pMap: [0]() ..

Когда я пытаюсь удалить эту пустую карту, мое приложение просто закрывается, и я получаю

Исключение первого шанса при 0xsomelocation в myapp.exe: 0xsomenumber: вызванный объект отключился от своих клиентов.

в окне вывода. Что это значит?

Спасибо ..

РЕДАКТИРОВАТЬ: Вот пример кода:

typedef map<const char*, StructA*, StructB> myMap;
typedef vector<myMap *> myMapStack;

StructB имеет перегруженный оператор () Редактировать: StructB - это действительно структура, извините, operator () - это просто функция сравнения строк ..

В некоторой части моего кода конструктор класса вызывает метод, давайте назовем его InitClass (), который инициализирует указатель myMap следующим образом:

pMyMap = new myMap; // I also tried this with new myMap()
// this pointer is then pushed onto the a map stack
pMyMapStack.push_back(pMyMap);

Позже в этом классе деструктор, я иду

pMyMap = pMyMapStack.back();
pMyMapStack.pop_back();

delete pMyMap; // after I step over this line the app quits.. and displays that message

Спасибо

РЕДАКТИРОВАТЬ: я вернулся к старой версии кода, который работал, и теперь он работает нормально ..

То, что сработало, было примерно так:

// after the pMyMapStack.pop_back()
int x = pMyMap->size();
if (x >= 0)
    delete pMyMap;

Ранее я изменил это на:

// after the pMyMapStack.pop_back()
int (x = pMyMap->size();
if (x >= 0){
    pMyMap->clear();
    delete pMyMap;
}

Странно ... Возможно, в коде что-то не так, но я просто не могу понять, где это еще ... Это слишком большой (и я, вероятно, уволен), если я выложу код целиком, так давайте просто оставим это на этом ..

Я думаю, это мог быть указатель на нулевую карту, которую я пытался очистить или удалить, что вызывало проблемы ..

Спасибо всем, кто пытался помочь ...:)

Ответы [ 6 ]

5 голосов
/ 01 марта 2010

Ну, есть много проблем с вашим примером кода. Все начинает идти не так, когда вы создаете карту как: <const char*, StructA*, StructB*> Есть ли причина для вас хранить указатели на карте вместо значений? В любом случае std::map скорее всего сохранит добавленные вами элементы в кучу. Также вы должны использовать std::string вместо const char*. Тогда нет абсолютно никакой причины передавать компаратор как указатель.

Опять же, это верно для вашего mapStack (Если вам нужен стек, почему бы вам не использовать его?). Пока вы не делитесь объектами или не используете чисто виртуальные базовые классы, нет причин использовать указатели. И если вам нужно использовать указатели, попробуйте не использовать необработанные указатели.

После того, как вы исправите эти ошибки, не должно быть никаких причин для использования new или delete.

1 голос
/ 01 марта 2010

Честно говоря, я думаю, что мы не пойдем без реального кода.

там может быть 101 место, где код ошибся, не ограничиваясь размещенным фрагментом.

из показанной реализации вставки и удаления объекта нет ни синтаксиса, ни логической ошибки. если исходный код был настолько ценным, чтобы поделиться им здесь, попробуйте создать фиктивный проект, достаточно простой, чтобы продемонстрировать проблему (если проблема не существует в фиктивном proj, вы знаете, что решаете неправильное направление)

1 голос
/ 01 марта 2010

Поскольку в вашем коде (который вы опубликовали) нет ничего, что могло бы вызвать эту проблему, я погуглил вашу строку с ошибкой и обнаружил, что это как-то связано с COM.

Этот пост может помочь вам: Чтоможет быть причина ошибки 0x80010108 (вызванный объект отключился от своих клиентов)?

Не имеет отношения к вопросу: я нахожу это интересным:

typedef map<const char*, StructA*, StructB*> myMap;

Как этоВаш третий параметр шаблона - это указатель struct ?Я предполагал, что это должен быть простой класс / тип.

1 голос
/ 01 марта 2010

Ты разбрасываешь указатели, как будто завтра нет. Наиболее вероятным объяснением является то, что вы сжимаете структуру своей карты, записывая через освобожденный (но не обнуляемый) указатель. Смотрите ответ pmr для большего количества предложений. Не используйте указатели, если вам не нужно. В вашем коде мало причин иметь дело с указателями карты, а не с объектами карты.

1 голос
/ 01 марта 2010

Вы должны сделать удаление, прежде чем выполнять pop_back ().

1 голос
/ 01 марта 2010

Просто выстрел в темноте, так как код недоступен. Вы уверены, что указатель на одну карту, а не массив карт (в этом случае вам нужно использовать delete [])?

...