Неправильные значения указателя внутри QMap

У меня возникла странная проблема, но это может быть причудой того, как работает 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 позже в исполнении это приводит к краху.

0

Решение

Значения на карте хранятся по значению, даже если в этом случае это означает, что указатель (адрес, на который он указывает) сохраняется по значению.
Например:

someType* toDelete1 = mySomeTypeMap.take(key);
someType* toDelete2 = mySomeTypeMap.take(key);
someType* toDelete3 = toDelete1;
toDelete1 = NULL;

toDelete2 & toDelete3 по-прежнему будет указывать на исходный объект

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

3

Другие решения

someType* toDelete = mySomeTypeMap.take(key);

Это переменная указателя, созданная в стеке, и ее значение установлено равным значению, которое вы сохраняете в карте. Вам не нужно устанавливать его в NULL, потому что он сразу выходит из области видимости.

take Функция удаляет указатель с карты, если вы используете его снова с тем же ключом, он вернет значение, созданное по умолчанию. Сразу после delete пробовать

mySomeTypeMap.insert(key, 0);
2

По вопросам рекламы [email protected]