Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.07.25;
Скачать: CL | DM;

Вниз

устанавливаю длину динамического массива и вылетаю :(   Найти похожие ветки 

 
Trubis   (2005-07-03 22:37) [0]

есть 4 динамических массива A,B,C,D
при сокращении их на 1 (dec(X)) и "обновлении":
SetLength(A,X);
SetLength(B,X);
SetLength(C,X);
SetLength(D,X);
вылетает на третьеё строке (здесь - на массиве С)
меняю местами - фиолетово - на ТРЕТЬЕЙ СТРОКЕ вылетает
где ошибка ?


 
P.N.P. ©   (2005-07-03 22:40) [1]

А что за ошибка-то?


 
Trubis   (2005-07-03 22:59) [2]

хз :)
если б я знал, спрашивал бы
вылетает на третьей строке (здесь - на массиве С)
т.е. при установке длины массива С
почему так происходит ?
если поменять местами массивы, всё равно вылетит. но только на ТРЕТЬЕЙ строке (т.е. при установки размера ТРЕТЬЕГО массива)


 
P.N.P. ©   (2005-07-03 23:02) [3]

>Trubis   (03.07.05 22:59) [2]
Текст ошибки какой?


 
Просто Джо ©   (2005-07-03 23:23) [4]

Объявление массивов, значение X и [3] - в студию.


 
Trubis   (2005-07-04 12:19) [5]

var (глобальный в Unit1)
A : array of string;
B : array of string;
C : array of string;
D : array of string;
X : integer;

FormCreate
X := 1;
SetLength(A,X);
SetLength(B,X);
SetLength(C,X);
SetLength(D,X);
A[0] := "1";
A[1] := "1";
B[0] := "1";
B[1] := "1";
C[0] := "1";
C[1] := "1";
D[0] := "1";
D[1] := "1";

Button1Click
(сокращаю массив на единичку)
X := 0;
SetLength(A,X);
SetLength(B,X);
SetLength(C,X); // программа молча вылетает
SetLength(D,X);

Если поменять местами строки, всё равно вылетит, не важно какой элемент (A,B,C или D) стоит в третьей строке. Может есть какие ограничение или тайные фичи?


 
Trubis   (2005-07-04 12:20) [6]

Молча - в смысле как будто нажал "Закрыть" (крестик в правом верхнем углу окна)


 
TUser ©   (2005-07-04 12:22) [7]

Когда ты сделал SetLength(ABCD,1), то там только один элемент - нулевой (их число - 1, а максимальный индекс - 0). Следовательно обращение к элементам A[1] и т.д. - это обращение к той области памяти, куда тебе нельзя лезть. Оно приводит к нарушениям в работе с информацией, записанной в памяти, а это может привести к чему угодно. В т.ч. и к вылетанию на третьей строчке.


 
dmitry501 ©   (2005-07-04 12:23) [8]

X := 1;
SetLength(A,X);
.....
A[0] := "1";
A[1] := "1";

Длину массива устанавливаешь равной 1, а значение присваиваешь двум элементам.


 
raidan ©   (2005-07-04 13:06) [9]

Размер динамического массива через SetLength - это число его элементов, как уже было сказано. Нумерация с нуля.


 
Trubis   (2005-07-04 13:06) [10]

а двоим первым массивам присваивается, да?
код набирал по памяти, может X = 2 ^))


 
Digitman ©   (2005-07-04 13:09) [11]


> а двоим


а они - одушевленные ?


 
Trubis   (2005-07-04 13:17) [12]

конечно!
иначе зачем им выёживаться :)


 
-=XP=- ©   (2005-07-04 13:19) [13]

и вылетаю...

Каким рейсом? Когда прибываете? И главное, куда?

Может есть какие ограничение или тайные фичи?

"Тайных" "фич" в программировании не бывает. "Фичи" бывают документированные и недокументированные. Судя по Вашему коду, Вы не знаете ни одних, ни других. SetLength задает количество элементов в массиве, а не индекс последнего элемента (как можно предположить из Вашего кода).

а двоим первым массивам присваивается, да?
код набирал по памяти, может X = 2 ^))


В общем случае не важно, что присваивается. Важно что при этом "затирается". Рекомендую впредь, если есть ошибки, писать код не "по памяти", а реальный.


 
Digitman ©   (2005-07-04 13:20) [14]

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


 
Trubis   (2005-07-04 21:29) [15]

с массивом разобрался:
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)


 
Eraser ©   (2005-07-04 23:14) [16]

Trubis   (04.07.05 21:29) [15]

Могу предположить что испорчен "базовый" адрес массива, т.е. указатель на данные.


 
Trubis   (2005-07-04 23:23) [17]

// Могу предположить что испорчен "базовый" адрес массива, т.е. указатель на данные.

А поподробнее.

Если поможет, то ещё такая деталь:
процедура, в которой происходит установка размеров массивов выполняется в программе несколько раз (по событию)
но такой глюк всегда со второго раза, причём ТОЛЬКО тогда, когда массив СОКРАЩАЕТСЯ
т.е. первый СОКРАЩАЮ на единичку - всё ОК, во второй раз - сабж
при УВЕЛИЧЕНИИ такого НЕ происходит


 
sniknik ©   (2005-07-04 23:27) [18]

> какая разница чему равен X - 0, 1 или 2 ???
подьезжем к сфветофору, и какая разница 1, 2 или 3 легковушки там стоит? ежели мы в БТР-е... отмеряем от светофора растояние на 2 машины и едем... ;о))

серьезно не догоняеш? или гониш?


 
Trubis   (2005-07-05 07:48) [19]

2sniknik
я так понял на единичку сокращать нельзя, а на два можно, так?


 
evvcom ©   (2005-07-05 08:14) [20]

Поставь птичку Range Checking. А в остальном похоже действительно гонишь.


 
sniknik ©   (2005-07-05 08:29) [21]

> я так понял на единичку сокращать нельзя, а на два можно, так?
бред. кто сказал? покажи кто и пойдем вместе морду ему набьем за дезинформацию. ;о))

вот чего нельзя, так это игнорировать размерность массивов и вылезать за пределы выделенной памяти.
а судя по тому как ты легкомысленно к этому относишся... это оно самое у тебя и есть...
вылез за пределы (гдето, не обязательно в том коде что показан), а раз присвоил чтото несушествуюшему то этим самым убил чтото полезное... указатель на данные/класс/структуру на что "повезет". следующее обрашение к "убитому" обьекту (у тебя это 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 после "порчи" не обращатся программа завершится коректно... вроде и ошибки нет. ;)


 
Anatoly Podgoretsky ©   (2005-07-05 08:42) [22]

Trubis   (03.07.05 22:37)  
В приведеном коде ошибки НЕТ!!!


 
Trubis   (2005-07-05 09:49) [23]

> //кранты массиву A

в программе совсем не используется:
- integer absolute A;
- High(A);

используется только SetLenght
для хранения размерности массивов используется глобальная переменная типа integer, поэтому нет нужды использовать High
она изменяется только в двух процедурах (в одной inc в другой dec), после чего сразу вызывается SetLenght для всех массивов (размер массивов одинаковый)

>В приведеном коде ошибки НЕТ!!!

В том-то и дело!
Первый раз сокращается - ошибок нет, утечек нет (контролируется Bounds Checker"ом), второй раз - на тебе.
Факт налицо! хз что надо делать, опять проект собирать заново и поэтапно отлаживать (по глюкам) :((


 
Anatoly Podgoretsky ©   (2005-07-05 09:54) [24]

Trubis   (05.07.05 09:49) [23]
Ну тебе же сказано, что в коде ошибки нет.


 
TUser ©   (2005-07-05 10:36) [25]

> Anatoly Podgoretsky

Ошибка в [5]. В чем она состоит дано уже указали. Но поскольку считается, что если использовать вместо константы переменную, то совершенно неважно, какое она принимает значение, то ошибка живет и торжествует.


 
sniknik ©   (2005-07-05 10:50) [26]

Trubis   (05.07.05 09:49) [23]
ты не расписывай словами как у тебя все чудесно в плане безглючного программирования...
выдели, как предлагал, то о чем сдесь пишеш в отдельный проект (минимизируй код), и посмотри. есть описываемый глюк? ложи сюда весь проект (новый!!! куда выделял), с этим глюком, он должен быть небольшим. тогда и будем говорить, а пока не о чем.
разве что о вере в чудеса.

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

> контролируется Bounds Checker"ом
он что контролирует? память или указатели/правильность присвоений? выкини его. даже если это полезная вещь. пользоваться ей ты все одно не умееш.



Страницы: 1 вся ветка

Текущий архив: 2005.07.25;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.039 c
14-1119592535
Игорь Шевченко
2005-06-24 09:55
2005.07.25
Юрий Зотов, с днем рождения!


4-1117126030
ancara
2005-05-26 20:47
2005.07.25
USB HID


14-1120460018
Chaster
2005-07-04 10:53
2005.07.25
PHP Dump


3-1118267255
highlander
2005-06-09 01:47
2005.07.25
Использование маски в QRDBText


1-1120633980
DeepProg
2005-07-06 11:13
2005.07.25
Передача данных из модельной формы в главную