#c #windows #qt #double
#c #Windows #qt #double
Вопрос:
Я встречаю два разных дампов strange и weird, которые оба связаны с двойным присвоением.
Предыстория
Существует QJsonValue(Qt5.0), похожее на это:
/*!
Assigns the value stored in a other to this object.
*/
QJsonValue amp;QJsonValue::operator =(const QJsonValue amp;other)
{
if (t == String amp;amp; stringData amp;amp; !stringData->ref.deref())
free(stringData);
t = other.t;
dbl = other.dbl;
if (d != other.d) {
if (d amp;amp; !d->ref.deref())
delete d;
d = other.d;
if (d)
d->ref.ref();
}
if (t == String amp;amp; stringData)
stringData->ref.ref();
return *this;
}
И затем, есть некоторая операция, подобная этой, она вызовет метод, описанный выше.
void test(QJsonObject obj, const QStringamp; key)
{
QJsonValue value = obj.value(key);
}
Dump1
Произошел сброс в dbl = other.dbl;
.
Информация об исключении этого дампа является:
Поток попытался прочитать или записать на виртуальный адрес, для которого у него нет соответствующего доступа.
Почему операция, которая просто копирует значение из other.dbl
в this.dbl
, вызовет исключение?
Dump2
Это также связано с операцией dbl = other.dbl
.
Было так странно, что значение this.dbl
не совпадает со значением other.dbl
.
PS
Интересно, что operator =
метод QJsonValue в Qt5.12 изменился, и я не знаю почему.
/*!
Assigns the value stored in a other to this object.
*/
QJsonValue amp;QJsonValue::operator =(const QJsonValue amp;other)
{
QJsonValue copy(other);
swap(copy);
return *this;
}
/*!
fn QJsonValue amp;QJsonValue::operator =(QJsonValue amp;amp;other)
since 5.10
Move-assigns a other to this value.
*/
/*!
fn void QJsonValue::swap(QJsonValue amp;other)
since 5.10
Swaps the value a other with this. This operation is very fast and never fails.
*/
Комментарии:
1. Я не слишком знаком с VS, но вы уверены, что не присваиваете значение nullptr? В вашем первом примере присваиваемый адрес является
0x43EF
довольно низким. Вы могли быassert(this != nullptr)
проверить это.2. В первом примере,
amp;dbl = 0x00cfceac {0.00000000000000000}
иamp;dbl = 0x00cfcd4c {8.416762146484e-315#DEN}
.this
не будетnullptr
, потому что объект определен в stack. Я не знаю, что0x43EF
означает адрес и как он генерируется.3. Если вы посмотрите внимательно, нарушение доступа на запись во втором примере произошло во время
stringData->ref.ref()
. Смотрите желтую стрелку в левом желобе. Таким образом, проблема не относится конкретно к double assignment, это просто проблема с памятью.4. Также вы смотрели на стек вызовов, чтобы убедиться, что вы действительно назначаете объект в стеке, а не где-то еще?
5.
stringData
иdbl
находятся в объединении. Таким образом, причина недействительностиstringData
заключается в том, что значениеdbl
не совпадает сother.dbl
. И я действительно уверен, что объект QJsonValue присваивается в стеке, точно так же, как операция, которую я пишу в вопросе.