Здравствуйте, Arturchik, Вы писали:
A>Например, такой код:
A>
A>myClass = class
A>{
A> void myClass() {}
A> double a;
A>}
A>...
A>myClass* с;
A>с = new myCalss();
A>c.a = 1.2;
A>
Ничего не понимаю. Это точно С++?
A>Точка останова на строку после последней, чтобы посмотреть чему равно значение c.a. Равно оно не 1.2, а чему-то левому.
Удивительное рядом. Как оно вообще скомпилировалось ?
A>Все это находится в большом проекте. Глазами уже устал искать ошибку. Подскажите, как бы Вы поступили в такой ситуации, что смотреть, за что хвататься?
Я бы первым делом проверил, что дебажу тот же самый код, что вижу на экране.
Всем привет. Недавно пришел к проблеме из которой пока не смог выпутаться.
Например, такой код:
myClass = class
{
void myClass() {}
double a;
}
...
myClass* с;
с = new myCalss();
c.a = 1.2;
Точка останова на строку после последней, чтобы посмотреть чему равно значение c.a. Равно оно не 1.2, а чему-то левому.
Все это находится в большом проекте. Глазами уже устал искать ошибку. Подскажите, как бы Вы поступили в такой ситуации, что смотреть, за что хвататься?
Здравствуйте, Arturchik, Вы писали:
A>Забыл добавить. A>Еще в myClass описан пустой виртуальный деструктор. Так вот, если его убрать, то здесь все работает, но повторяется ошибка в другом месте.
Виртуальный деструктор => наличие виртуальных функций => указатель на таблицу виртуальных функций vfptr по нулевому смещению в теле класса.
Попробуй вместо деструктора в самое начало класса добавить void* dummy.
Кстати говоря, если отлаживать в релизе, т.е. со включёнными оптимизациями, там могут быть редкостные чудеса.
Надеюсь, этот фактор уже учтён?
Здравствуйте, Arturchik, Вы писали:
A>Точка останова на строку после последней, чтобы посмотреть чему равно значение c.a. Равно оно не 1.2, а чему-то левому.
A>Все это находится в большом проекте. Глазами уже устал искать ошибку. Подскажите, как бы Вы поступили в такой ситуации, что смотреть, за что хвататься?
ну к примеру ставишь точку останова на изменение адреса c.a и смотришь, где сработало
Не срабатывает остановка. Значение после создания объекта = 0, после выполнения присваивания значение = ерудне, но точка останова на изменение c.a не срабатывает.
Забыл добавить.
Еще в myClass описан пустой виртуальный деструктор. Так вот, если его убрать, то здесь все работает, но повторяется ошибка в другом месте.
Здравствуйте, Arturchik, Вы писали:
A>Здравствуйте, enji.
A>Не срабатывает остановка. Значение после создания объекта = 0, после выполнения присваивания значение = ерудне, но точка останова на изменение c.a не срабатывает.
У вас скорее всего перетирается стек на котором лежит указатель на объект. Поставьте бряк на модификацию укзателя.
A>Всем привет. Недавно пришел к проблеме из которой пока не смог выпутаться.
A>Например, такой код:
A>
A>myClass = class
A>{
A> void myClass() {}
A> double a;
A>}
A>...
A>myClass* с;
A>с = new myCalss();
A>c.a = 1.2;
A>
A>Точка останова на строку после последней, чтобы посмотреть чему равно значение c.a. Равно оно не 1.2, а чему-то левому. A>Все это находится в большом проекте. Глазами уже устал искать ошибку. Подскажите, как бы Вы поступили в такой ситуации, что смотреть, за что хвататься?
Здравствуйте, Кодт, Вы писали:
К>Виртуальный деструктор => наличие виртуальных функций => указатель на таблицу виртуальных функций vfptr по нулевому смещению в теле класса. К>Попробуй вместо деструктора в самое начало класса добавить void* dummy.
К>Кстати говоря, если отлаживать в релизе, т.е. со включёнными оптимизациями, там могут быть редкостные чудеса. К>Надеюсь, этот фактор уже учтён?
Добавил void* dummy в начало класса, убрал деструктор. Такая же свистопляска. Какой я из этого должен сделать вывод?
Здравствуйте, saf_e, Вы писали:
_>У вас скорее всего перетирается стек на котором лежит указатель на объект. Поставьте бряк на модификацию укзателя.
_>Т.е. на адрес: &c
Оператор new выделил память и вернул указатель на 0x0012ecd4
В конструкторе объекта &this = 0x0012ecdc
На операторе присваивания через Immediate Window адрес объекта 0x0012ed28, а если мышку навести на экземпляр класса в коде, то в плавающем окошке адрес = 0x0ad50870.
Поставил брейкпоинт на изменение адреса pResult в операторе new. Брейк сработал в atltime.inl:
Здравствуйте, Arturchik, Вы писали:
A>Добавил void* dummy в начало класса, убрал деструктор. Такая же свистопляска. Какой я из этого должен сделать вывод?
Вывод такой, что виной всему лэяут класса.
Больше всего похоже на нарушение ODR.
Где-то существует определение этого класса, в котором этого указателя нет.
Например, какой-нибудь объектный файл, который почему-то не перекомпилируется (сбитая дата, сломанные зависимости, DLL hell и т.п.)
Здравствуйте, Кодт, Вы писали:
К>Вывод такой, что виной всему лэяут класса.
К>Больше всего похоже на нарушение ODR. К>Где-то существует определение этого класса, в котором этого указателя нет. К>Например, какой-нибудь объектный файл, который почему-то не перекомпилируется (сбитая дата, сломанные зависимости, DLL hell и т.п.)
Может быть проблема в следующем:
Я использую второй проект (Managed C++) для связи с модулями на C#. Там есть такой код:
#ifdef _MANAGED
//Эти функции существуют только в управляемом коде
CManagedObject(System::Object^ managed);
System::Object^ GetObject() const {return managed_;}
#endif//_MANAGED
То есть, для моего проекта (native C++) модуль с приведенным выше кодом будет скомпилирован отдельно, в урезанном виде?
A>адрес ti->TO не изменяется, Data Breakpoint &ti->TO на присваивании не срабатывает...
A>Еще раз прошу прощения за свою непунктуальность
С какой стати адрес ti->TO должен изменяться? И нахрена тебе нужен дата брейкпойнт?
Лучше ответь себе на вопрос, сколько раз ты выполняешь new TurbulenceInfo() и сколько после этого выполняешь delete для твоих турбуленсинфо? Судя по приведённым огрызкам кода — ни разу.
Здравствуйте, alexku, Вы писали:
A>С какой стати адрес ti->TO должен изменяться? И нахрена тебе нужен дата брейкпойнт? A>Лучше ответь себе на вопрос, сколько раз ты выполняешь new TurbulenceInfo() и сколько после этого выполняешь delete для твоих турбуленсинфо? Судя по приведённым огрызкам кода — ни разу.
1.
Самый первый ответ был от enji: A>ну к примеру ставишь точку останова на изменение адреса c.a и смотришь, где сработало
Может я что-то неправильно понял -- поправьте. Адрес c.a (эквив. ti->TO) не изменился.
Дата брейкпоинт должен сработать при изменении значения переменной c.a (ti->TO в новом варианте), но присваивание выполнил, а брейкпоинт не сроботал.
2.
Отвечу себе на этот вопрос вслух: new выполняю один раз, delete выполняй-не выполняй, результат не меняется
Получилось так:
в m_dummy_debug_1 последние 4 байта изменились. Попробовал
(double&)&ti->m_dummy_debug_1[60]
И, действительно, получил то, что должно быть в TO, т.е. все съехало на 4 байта.
m_dummy_debug_2 не изменился.
Добавил void* dummy; в начало класса. Выполняю присваивание ti->time = (CTime)123456; Получилось так:
m_dummy_debug_1 не изменился.
m_dummy_debug_2 первые 8 байт обнулилиись.
ti->time = ерунда
(__time64_t&)&ti->m_dummy_debug_2[-11] = то, что я записывал в ti->time
Очень похоже на нарушение ODR.
По причинам:
— или что-то перекомпилируется с отставанием на такт
— или где-то стоит #define double float или какое-нибудь похожее заподло
— или где-то включена #pragma pack, и она распространилась на твою структуру, — а где-то она не включена и не распространилась
Прошу прощения, с первого раза не вкурил, о чём речь.
Видимо TurbulenceInfo объявлена где-то ещё с другим набором или порядком мемберов. Попробуй своё объявление обернуть в namespace и указывать его явно при использовании. Или назови по-другому.