Динамические массивы в объектах (Delphi 7).

Алексей Вк.
Дата: 06.12.2007 16:39:55
Если точнее - то странное поведение, в общем пример:
процедура М, при входе в нее создается объект, при выходе делаем ему Free.
Объект содержит несколько динамичесих массивов, при создании и разрушении объекта обнуляем длину этих массивов. Один из массивов(А) в качестве элементов содеhжит запись, которая в свою очередь содержит динамический массив (Б), для добавления элементов в массив А вызываем одну единственную процедуру П, которая после добавления элемента сразу обнуляет длину массива Б.
И вот теперь очень трудно уловимый глюк.
Иногда после добавления элемента в массив А длина массива Б после выхода из процедуры П отлична от нуля и сам массив Б заполнен мусором. Это естественно приводит к падению алгоритмов дальнейшей обработки.
К сожалению не могу привести весь текст (весьма объемный), хотя отдельные участки вполне могу, только скажите что интересует.
Как я понимаю - это следствие некорректной работы с памятью, но т.к. напрямую указатели не использую, то подозреваю что виноват компилятор, может есть какой-то update? конечно в вероятностью 99.9 виноват я сам, но чем можно отловить такую проблему, есть ли утилиты, позволяющие контролировать распределение памяти в работающей программе. К сожалению в автономных отладчиках я не силен, программу на ассемблере отладить смогу, а вот на Delphi - нет.

Да - самая большая проблема - основная процедура М вызывается десятки раз, работа каждый раз идет с использованием Random, так что параметры непостоянны, а сама ошибка может выскакивать в любой момент. Сейчас она делает это часто, так что ловить саму ошибку могу, вот только где.
Да и ошибка появилась только после того как я перевел большую часть объемного процедурного кода процедуры М в вышеописанный объект, работать стало проще, но вот в результате получил вот такую ошибку, ранее в процедурном виде этот код работал без подобных сбоев.
ambarka_max
Дата: 06.12.2007 16:54:03
По моему, да, по моему... тут 100% где-то элементу массива с индексом за диапазоном массива присваевается что-то. В этом случае ошибки сразу может и не быть, зато потом...

Если есть циклы, проверяй диапазон значений индекса. Если есть процедуры, куда передается индекс элемента массива, внутри всегда проверяй на вхождение в диапазон [0..length-1]
Алексей Вк.
Дата: 06.12.2007 17:02:03
ambarka_max
По моему, да, по моему... тут 100% где-то элементу массива с индексом за диапазоном массива присваевается что-то. В этом случае ошибки сразу может и не быть, зато потом...

Если есть циклы, проверяй диапазон значений индекса. Если есть процедуры, куда передается индекс элемента массива, внутри всегда проверяй на вхождение в диапазон [0..length-1]

Я вот сейчас этим и занимаюсь - делаю кучу проверок, ставлю везде try-except на каждый логичесикй блок, чтобы выяснить значение переменных.
Но просто у меня уже так раз было, форма с компонентами DevExpress, своих обектов в ней нет,
она создается динамически и вызывается достаточно часто - сотни раз за день, тут же и освобождается, изредка - раз в неделю - месяц поля обьектов DevExpress оказываются заполенными старыми данными, еще с прошлого раза - с предыдущего вызова формы, но ведь этого не должно было бы быть чисто логически. Отловил ошибку просто вызовом сообщений со значениями переменных, и на том остановился, сам устранить не смог, больно редкая ситуация, поэтому просто выдал рекомендации операторам по ее устранению, хотя спать спокойно данный глюк не дает.
Теперь ну очень хочу перейти на 2007 (win32) с надеждой что хоть этот глюк там исчезнет, хотя конечно этого может и не произойти. Но это будет позже, сейчас нет времени.
Entaro Adun
Дата: 06.12.2007 17:12:40
Алексей Вк.
но чем можно отловить такую проблему, есть ли утилиты, позволяющие контролировать распределение памяти в работающей программе.

MemProof
Алексей Вк.
Дата: 06.12.2007 17:16:12
Entaro Adun
Алексей Вк.
но чем можно отловить такую проблему, есть ли утилиты, позволяющие контролировать распределение памяти в работающей программе.

MemProof

Благодарю!
Алексей Вк.
Дата: 06.12.2007 18:49:54
Повезло :-)
Нашел ошибку, свою соственную - обращался по индексу "-1" к динамическому массиву через property объекта (read write напрямую к внутреннему массиву), кстати - по идее такое обращение должно было бы вызвать исключение связанное с границей диапазона? Или здесь оно не контролируется?
Упырь2
Дата: 07.12.2007 11:46:45
Это зависит от настроек компилятора, см. {$RANGECHECKS ON} or {$RANGECHECKS OFF}
Petro123
Дата: 07.12.2007 11:52:36
вместо динамических массивов используй динамический массив классов-объектов (да хоть на TList).
Рессурсы не увеличатся, а работа с памятью упорядочится.
______________________________________________
Вы имеете право хранить молчание! Всё что Вы скажете может быть использовано против Вас в суде!
Petro123
Дата: 07.12.2007 11:58:19
Алексей Вк

Но просто у меня уже так раз было, форма с компонентами DevExpress, своих обектов в ней нет,
она создается динамически и вызывается достаточно часто - сотни раз за день, тут же и освобождается, изредка - раз в неделю - месяц поля обьектов DevExpress оказываются заполенными старыми данными, еще с прошлого раза - с предыдущего вызова формы, но ведь этого не должно было бы быть чисто логически.

IMHO ООП здесь мало
Алексей Вк.
Дата: 07.12.2007 14:26:12
Petro123
вместо динамических массивов используй динамический массив классов-объектов (да хоть на TList).
Рессурсы не увеличатся, а работа с памятью упорядочится.
______________________________________________
Вы имеете право хранить молчание! Всё что Вы скажете может быть использовано против Вас в суде!

Хочется, но почему-то изначально с ними не сложилось, хоть и удобны они, но по старой привычке использую массивы, Совет хороший, попробую прислушаться.