![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
устанавливаю длину динамического массива и вылетаю :( [D6, Win95/98]
Trubis © (2005-07-03 22:37:00)есть 4 динамических массива A,B,C,D
при сокращении их на 1 (dec(X)) и "обновлении":
SetLength(A,X);
SetLength(B,X);
SetLength(C,X);
SetLength(D,X);
вылетает на третьеё строке (здесь - на массиве С)
меняю местами - фиолетово - на ТРЕТЬЕЙ СТРОКЕ вылетает
где ошибка ?
sniknik (2005-07-05 10:50:00) [1]Trubis (05.07.05 09:49) [23]
ты не расписывай словами как у тебя все чудесно в плане безглючного программирования...
выдели, как предлагал, то о чем сдесь пишеш в отдельный проект (минимизируй код), и посмотри. есть описываемый глюк? ложи сюда весь проект (новый!!! куда выделял), с этим глюком, он должен быть небольшим. тогда и будем говорить, а пока не о чем.
разве что о вере в чудеса.
> в программе совсем не используется: ...
ты значение слова примерзнаеш?
и что тебе неясно в написанной руским языком фразе
> тут сознательно, а у тебя случайно, тем что ты пишеш "в никуда" за границами массива.
???
сбить указатель можно не единственным способом. найди тот что у тебя и ты найдеш глюк. но большое подозрение конечно на выход за границу массива... судя по безалаберному отношению к этим границам высказанном в этой ветке.
> контролируется Bounds Checker'ом
он что контролирует? память или указатели/правильность присвоений? выкини его. даже если это полезная вещь. пользоваться ей ты все одно не умееш.
TUser (2005-07-05 10:36:00) [2]> Anatoly Podgoretsky
Ошибка в [5]. В чем она состоит дано уже указали. Но поскольку считается, что если использовать вместо константы переменную, то совершенно неважно, какое она принимает значение, то ошибка живет и торжествует.
Anatoly Podgoretsky (2005-07-05 09:54:00) [3]Trubis (05.07.05 09:49) [23]
Ну тебе же сказано, что в коде ошибки нет.
Trubis (2005-07-05 09:49:00) [4]> //кранты массиву A
в программе совсем не используется:
- integer absolute A;
- High(A);
используется только SetLenght
для хранения размерности массивов используется глобальная переменная типа integer, поэтому нет нужды использовать High
она изменяется только в двух процедурах (в одной inc в другой dec), после чего сразу вызывается SetLenght для всех массивов (размер массивов одинаковый)
>В приведеном коде ошибки НЕТ!!!
В том-то и дело!
Первый раз сокращается - ошибок нет, утечек нет (контролируется Bounds Checker'ом), второй раз - на тебе.
Факт налицо! хз что надо делать, опять проект собирать заново и поэтапно отлаживать (по глюкам) :((
Anatoly Podgoretsky (2005-07-05 08:42:00) [5]Trubis (03.07.05 22:37)
В приведеном коде ошибки НЕТ!!!
sniknik (2005-07-05 08:29:00) [6]> я так понял на единичку сокращать нельзя, а на два можно, так?
бред. кто сказал? покажи кто и пойдем вместе морду ему набьем за дезинформацию. ;о))
вот чего нельзя, так это игнорировать размерность массивов и вылезать за пределы выделенной памяти.
а судя по тому как ты легкомысленно к этому относишся... это оно самое у тебя и есть...
вылез за пределы (гдето, не обязательно в том коде что показан), а раз присвоил чтото несушествуюшему то этим самым убил чтото полезное... указатель на данные/класс/структуру на что "повезет". следующее обрашение к "убитому" обьекту (у тебя это 3й масив, судя по описанию) закончится "трагически"... а может (при необращении) даже и завершится нормально, типа без глюков...
проверь сам, вынеси все что показал в новый, "чистый" проэкт, и сделай уменьшение размерности (хоть на 2 хоть на 1), глюка не будет...
(если верно то что в > Trubis (04.07.05 21:29) [15]
...
в этом ошибок нет (и не было))
пример, сознательно портим адрес...
var
A : array of string;
B : array of string;
C : array of string;
D : array of string;
X : integer;
P : integer absolute A;
procedure TForm1.Button1Click(Sender: TObject);
begin
X:= High(A); //меньше на 1
P:= 1; //кранты массиву A
SetLength(A, X);
SetLength(B, X);
SetLength(C, X); // программа молча вылетает //а вот до сюда ты не дойдеш...
SetLength(D, X);
end;
тут сознательно, а у тебя случайно, тем что ты пишеш "в никуда" за границами массива.
и заметь, если к массиву A после "порчи" не обращатся программа завершится коректно... вроде и ошибки нет. ;)
evvcom (2005-07-05 08:14:00) [7]Поставь птичку Range Checking. А в остальном похоже действительно гонишь.
Trubis (2005-07-05 07:48:00) [8]2sniknik
я так понял на единичку сокращать нельзя, а на два можно, так?
sniknik (2005-07-04 23:27:00) [9]> какая разница чему равен X - 0, 1 или 2 ???
подьезжем к сфветофору, и какая разница 1, 2 или 3 легковушки там стоит? ежели мы в БТР-е... отмеряем от светофора растояние на 2 машины и едем... ;о))
серьезно не догоняеш? или гониш?
Trubis (2005-07-04 23:23:00) [10]// Могу предположить что испорчен "базовый" адрес массива, т.е. указатель на данные.
А поподробнее.
Если поможет, то ещё такая деталь:
процедура, в которой происходит установка размеров массивов выполняется в программе несколько раз (по событию)
но такой глюк всегда со второго раза, причём ТОЛЬКО тогда, когда массив СОКРАЩАЕТСЯ
т.е. первый СОКРАЩАЮ на единичку - всё ОК, во второй раз - сабж
при УВЕЛИЧЕНИИ такого НЕ происходит
Eraser (2005-07-04 23:14:00) [11]Trubis (04.07.05 21:29) [15]
Могу предположить что испорчен "базовый" адрес массива, т.е. указатель на данные.
Trubis (2005-07-04 21:29:00) [12]с массивом разобрался:
SetLength(A,4) - элементов 4
имеем: A[0], A[1], A[2], A[3]
в этом ошибок нет (и не было)
приходиться повториться снова
SetLength(A,X);
SetLength(B,X);
SetLength(C,X);
SetLength(D,X);
какая разница чему равен X - 0, 1 или 2 ???
SetLength задает размер динамического массива, правильно ?
важно ли сколько и какие элементы были в нем до этого ?
почему при установке размера массива С происходит завершение программы (никаких ошибок он не показывает - просто завершается, как-будто выполнили Halt) ?
пошаговое выполнение - доходит до SetLength(C,X) (выделяет синей полосой). нажимаю F8 и это равносильно тому, что нажал Ctrl+F2 (т.е. Program Reset)
Digitman (2005-07-04 13:20:00) [13]они и не выеживаются.
выёживаешься-тио ты, а не они)
а выёживаться желательно при поддержке фактов, полученных в рез-те пошаговой трассировки кода средствами встр.отладчика.
-=XP=- (2005-07-04 13:19:00) [14]и вылетаю...
Каким рейсом? Когда прибываете? И главное, куда?
Может есть какие ограничение или тайные фичи?
"Тайных" "фич" в программировании не бывает. "Фичи" бывают документированные и недокументированные. Судя по Вашему коду, Вы не знаете ни одних, ни других. SetLength задает количествоэлементов в массиве, а не индекс последнего элемента (как можно предположить из Вашего кода).
а двоим первым массивам присваивается, да?
код набирал по памяти, может X = 2 ^))
В общем случае не важно, что присваивается. Важно что при этом "затирается". Рекомендую впредь, если есть ошибки, писать код не "по памяти", а реальный.
Trubis (2005-07-04 13:17:00) [15]конечно!
иначе зачем им выёживаться :)
Digitman (2005-07-04 13:09:00) [16]
> а двоим
а они - одушевленные ?
Trubis (2005-07-04 13:06:00) [17]а двоим первым массивам присваивается, да?
код набирал по памяти, может X = 2 ^))
raidan (2005-07-04 13:06:00) [18]Размер динамического массива через SetLength - это число его элементов, как уже было сказано. Нумерация с нуля.
dmitry501 (2005-07-04 12:23:00) [19]
X := 1;
SetLength(A,X);
.....
A[0] := '1';
A[1] := '1';
Длину массива устанавливаешь равной 1, а значение присваиваешь двум элементам.
TUser (2005-07-04 12:22:00) [20]Когда ты сделал SetLength(ABCD,1), то там только один элемент - нулевой (их число - 1, а максимальный индекс - 0). Следовательно обращение к элементам A[1] и т.д. - это обращение к той области памяти, куда тебе нельзя лезть. Оно приводит к нарушениям в работе с информацией, записанной в памяти, а это может привести к чему угодно. В т.ч. и к вылетанию на третьей строчке.