Сейчас на форуме: zds (+5 невидимых) |
eXeL@B —› Программирование —› Неверное объявление переменных в стеке |
Посл.ответ | Сообщение |
|
Создано: 02 марта 2014 21:32 · Поправил: Wagos · Личное сообщение · #1 Добрый вечер. Создал отдельную тему для данного вопроса. Продолжаю войну с компилятором Embarcadero (или со своей невнимательностью). Проблема следующая: в конструкторе класса производится инициализация внутренних переменных класса (public). К примеру: a = 1. При компиляции имеем следующие команды: Code:
Программа пишет значение 1 в память, причем адрес ячейки отличается от &a на 18h (&a_real - &a = 18h, где &a_real - адрес реальной ячейки памяти, куда пишется значение; &a - адрес ячейки памяти, в которую должно писаться значение, но не пишется). Экземпляр класса создается через операцию new в обработчике события создания формы. Причем, программа работает нормально - все аргументы нормально передаются в функции и обрабатываются (пока сбоев на этой почве не обнаружил). Программу невозможно отлаживать - в Watch'ах вместо нормальных значений выводится всякий мусор. + бонусный глюк, который удалось обнаружить. При добавлении некоторых переменных(внутренних public'овых переменных класса) в Watch в Embarcadero'вский отладчик, он начинает ругаться, что таких переменных вообще не существует (Добавляю в Watch, как this->var, или object->var), хотя, при компиляции данные переменные были отлично обработаны. У кого возникали подобные проблемы? |
|
Создано: 02 марта 2014 23:15 · Поправил: ajax · Личное сообщение · #2 |
|
Создано: 02 марта 2014 23:22 · Поправил: kunix · Личное сообщение · #3 |
|
Создано: 02 марта 2014 23:36 · Поправил: Wagos · Личное сообщение · #4 ajax, Не понял, можно ещё раз? Что кто упускает? kunix, Нет, родительского класса нет. Объект непосредственно от написанного класса, который ни от чего не наследуется. Проблем не было, пока не написал пару рекурсивных функций в классе. (которые используются намного позже инициализации) Снес эти функции - проблемы всё равно остались и так и не исчезли. По поводу RTTI - хз. По-идее, в отладчик должна передаваться информация, которую можно использовать для отладки. Хотя, возможно, отладчик на@бнулся, но я с таким ни разу не сталкивался. Откомпилировал с помощью GNU - та-же проблема. Видимо, что-то с настройками компилятора. |
|
Создано: 03 марта 2014 09:32 · Поправил: DenCoder · Личное сообщение · #5 Wagos Если ничего не упустили, то могу предположить только одну возможную причину: компилятор резервирует некоторую область для своих целей Что в 6 двордах до переменной? 1. Embarcadero Delphi (ранее наз. CodeGear Delphi и Borland Delphi) — наверное, самый известный компилятор, который является последователем Borland Pascal и Turbo Pascal. 2. Турбо Паскаль, начиная с версии 5.5, добавил в Паскаль объектно-ориентированные свойства, а в Object Pascal — динамическую идентификацию типа данных с возможностью доступа к метаданным классов (то есть к описанию классов и их членов) в компилируемом коде, также называемом интроспекцией — данная технология получила обозначение RTTI. Так как все классы наследуют функции базового класса TObject, то любой указатель на объект можно преобразовать к нему, после чего воспользоваться методом ClassType и функцией TypeInfo, которые и обеспечат интроспекцию. Я бы провёл исследование, в каком порядке в скомпилированном коде хранится. Домашнее задание Вам 1) 2) Таблица методов-членов класса. Указатель на таблицу или целиком массив? 3) Поля-члены класса 4) Таблица методов-членов родительского класса TObject. Указатель на таблицу или целиком массив? 5) Поля-члены родительского класса. ----- IZ.RU | Сообщение посчитали полезным: Wagos |
|
Создано: 03 марта 2014 23:22 · Личное сообщение · #6 |
|
Создано: 04 марта 2014 13:59 · Поправил: Wagos · Личное сообщение · #7 Решение найдено. Приношу извинения разработчикам компилятора за желание их расстрелять и четвертовать. С помощью универсального способа поиска неисправностей (всё закомментировать и раскомментировать до тех пор, пока не появятся ошибки), решение было найдено. Причина проблемы оказалась в следующем: Программа состоит из 3-х модулей: VCL(с формой), мой класс и отдельным модулем идут потоки, наследуемые от класса TThread. О них-то я и забыл. Также, эти модули используют 2 header'a: первый - стандартный (создается при создании проекта), второй - описывает переменные класса и потоков. Однажды мне пришлось обновить header класса и потоков, внеся туда некоторые изменения. Я сохранил его как отдельный файл и обновил #include в cpp-файле класса, забыв при этом обновить его в файле потоков!!! Поначалу проблемы были незаметны, но, вписав туда большую структуру, у меня поплыли адреса, т. к. класс - использует один header, а потоки - используют другой. Вот, собственно и всё. Builder - невиновен. Внимательность - залог всего. |
eXeL@B —› Программирование —› Неверное объявление переменных в стеке |