У меня возникла странная проблема, но это может быть причудой того, как работает QMap, и я просто не понимаю ее. Трудно подвести итог проблемы, но я сделаю все возможное.
У меня есть класс A
с QMap<QString, someType*> mySomeTypeMap;
, Когда я загружаю новый файл в свою программу, я хочу удалить все содержимое этого QMap
так что я могу заселить его новыми данными. Я делаю это следующим образом:
foreach (QString key, mySomeTypeMap.keys())
{
someType* toDelete = mySomeTypeMap.take(key);
//Show me the original address of the pointer
qDebug() << "toDelete: " << toDelete;
delete toDelete;
//Set the pointer to 0x0
toDelete = NULL;
}
qDebug()
оператор выводит правильный адрес значения, которое я хочу удалить, и когда я смотрю на toDelete
в отладчике после того, как он установлен в NULL
, это говорит 0x0, что я и хочу.
Потом в другом классе B
У меня есть следующий код …
void B::setSomeType(someType* blah)
{
if (Blah != NULL)
{
//Calls a bunch of disconnect()'s
disconnectAllSignals();
Blah = blah;
//Calls a bunch of connect()'s
connectAllSignals();
}
}
Что действительно сбивает с толку, так это то, что моя программа аварийно завершает работу, когда disconnectAllSignals();
линия. Причина в том, что он пытается позвонить disconnect()
на Blah
который был удален и должен был быть установлен в 0x0, когда я установил его NULL
, Тем не менее, если он на самом деле был установлен на NULL
он никогда бы не вошел в этот блок if. В отладчике я вижу, что адрес Blah
точно так же, как то, что я получаю при распечатке qDebug() << "toDelete: " << toDelete;
прямо перед настройкой toDelete = NULL;
,
TLDR; Я не знаю, как моя программа возвращает оригинальный адрес указателя после того, как я удаляю указатель и устанавливаю тот же указатель на NULL
, Поскольку указатель не установлен в NULL
позже в исполнении это приводит к краху.
Значения на карте хранятся по значению, даже если в этом случае это означает, что указатель (адрес, на который он указывает) сохраняется по значению.
Например:
someType* toDelete1 = mySomeTypeMap.take(key);
someType* toDelete2 = mySomeTypeMap.take(key);
someType* toDelete3 = toDelete1;
toDelete1 = NULL;
toDelete2 & toDelete3 по-прежнему будет указывать на исходный объект
Вместо того чтобы указатель становился нулевым после удаления, вы должны либо удалить его с карты, либо установить для этого ключа значение NULL.
someType* toDelete = mySomeTypeMap.take(key);
Это переменная указателя, созданная в стеке, и ее значение установлено равным значению, которое вы сохраняете в карте. Вам не нужно устанавливать его в NULL, потому что он сразу выходит из области видимости.
take
Функция удаляет указатель с карты, если вы используете его снова с тем же ключом, он вернет значение, созданное по умолчанию. Сразу после delete
пробовать
mySomeTypeMap.insert(key, 0);