|
Делфи. Не работает Setlength | ☑ | ||
---|---|---|---|---|
0
Kseniya_
17.11.15
✎
14:56
|
Здравствуйте! Появилась довольно странная проблема, не могу сообразить, как решить её или чем заменить код, чтобы программа работала.
У меня в цикле происходят различные действия с массивом. Он заполняется и, как всегда, сначала добавляем новый элемент (увеличиваем размерность массива на 1цу), тут все и ломается, на этом шаге. setlength(Polypoints, POintCount + 1); setlength сначала срабатывает первые 408 итераций цикла, а затем ломается на 409 шаге. Тип массив структуры type TDPoint = record X, Y: single; end; Polypoints: array of TDPOint; Кто сталкивался с таким? Что нужно поменять, чтобы все работало? Может быть, это связано с типом массива? |
|||
1
Гёдза
17.11.15
✎
14:57
|
а что в делфях arraylist нету что ли?
|
|||
2
Asmody
17.11.15
✎
14:58
|
Вы всё еще пишите на дельфи?!
|
|||
3
Господин ПЖ
17.11.15
✎
14:59
|
>а затем ломается на 409 шаге.
я бы тоже сломался |
|||
4
Господин ПЖ
17.11.15
✎
14:59
|
дельфи проклят богом
|
|||
5
H A D G E H O G s
17.11.15
✎
14:59
|
Где то поврежденная область памяти, не в этом коде
|
|||
6
Kseniya_
17.11.15
✎
15:04
|
Есть ещё такая ошибка в модуле с ассемблерным кодом, тут на память похоже.
первая такая - тут вообще не понимаю, где искать истоки fastmm4 mov TMediumFreeBlock[eax].PreviousFreeBlock, edi и вторая {Get the new first free block} and ecx, [eax - 4] |
|||
7
vde69
17.11.15
✎
15:04
|
во первых есть объект list, он динамический, с ним так можно работать (он может располагается в прерывистом диапазоне памяти)....
объект array - статический, под него выделяется единый кусок памяти, если в единый кусок не влезает - беда.... |
|||
8
Kseniya_
17.11.15
✎
15:05
|
Да, пишу на делфи) А что же в нем плохого, расскажите.
|
|||
9
Kseniya_
17.11.15
✎
15:08
|
(7) Понятно, спасибо. Стоит попробовать заменить на список все (программа просто громадная). Надеюсь, сделаю код лучше. А памяти программа должна много использовать.
|
|||
10
H A D G E H O G s
17.11.15
✎
15:08
|
(7) Ты как всегда плаваешь в технической реализации.
|
|||
11
H A D G E H O G s
17.11.15
✎
15:10
|
(9) не поможет. Решите связный список руками. Вде дятлит, но неудивительно, я раньше тоже щетал tlist связным списком
|
|||
12
Kseniya_
17.11.15
✎
15:11
|
(11) То есть реализовать список, а тип TList не использовать?
|
|||
13
vde69
17.11.15
✎
15:13
|
(11) tlist - связный список, по тому как под каждый экземпляр объекта требуется явным образом выделять память
|
|||
14
Ненавижу 1С
гуру
17.11.15
✎
15:14
|
(13) при отсутствии выделенной памяти и добавлении элемента, там выделяется сразу блок не на один элемент
|
|||
15
H A D G E H O G s
17.11.15
✎
15:15
|
(13) tlist - динамический массив указателей
|
|||
16
Kseniya_
17.11.15
✎
15:17
|
(15) Спасибо! Попробую сделать так.
|
|||
17
Гёдза
17.11.15
✎
15:17
|
(15) те tlist - это все-таки arraylist?
|
|||
18
H A D G E H O G s
17.11.15
✎
15:18
|
Хотя да, автору tlist поможет. Реалокировать указатели на данные проще чем сами непрерывные данные
|
|||
19
H A D G E H O G s
17.11.15
✎
15:20
|
Я всегда делаю наследника tlist под конкретный случай и переписываю добавление элемента, очистку и уничтожение.
|
|||
20
Гёдза
17.11.15
✎
15:20
|
В яве чтоб каждый раз по 1 элементу не прибавлять базовый массив удваивают
|
|||
21
H A D G E H O G s
17.11.15
✎
15:23
|
(20) извращи.
Программист либо должен знать конечный размер либо пользовать связный список. Tlist кстати, красивый пример компромисс. |
|||
22
Serginio1
17.11.15
✎
15:25
|
(20) Это делают везде. Просто в Delphi увеличивают на 40% и при частых использовании натыкаются на фрагментацию памяти. Специально делал сегментированный классы
http://catalog.mista.ru/public/345658/ http://rsdn.ru/forum/src/450320.1 |
|||
23
Кирпич
17.11.15
✎
15:26
|
(0) код покажи. ошибка скорее всего не в этом
|
|||
24
Гёдза
17.11.15
✎
15:45
|
(21) связный список медленно по индексу получает
|
|||
25
Serginio1
17.11.15
✎
15:57
|
(24) Такой не очень медленно http://rsdn.ru/forum/src/450320.1
|
|||
26
Kseniya_
18.11.15
✎
09:34
|
(23) Код настолько огромен, что его и не выложить. Примерно такой:
ююю BackCount := 0; while (BackCount < 50) and (Linecount - BackCount > 2) do begin PlaceOfError := 30; if PointOfIntersectionLines(RoadLines[Linecount], RoadLines[Linecount - BackCount - 2]) then begin Range := BackCount + 2; PlaceOfError := 31; for N := Linecount - BackCount - 1 to POintCount - 1 - Range do Polypoints[N] := Polypoints[N + Range]; PlaceOfError := 317; POintCount := POintCount - Range; PlaceOfError := 318; setlength(Polypoints, POintCount); PlaceOfError := 319; Linecount := Linecount - BackCount - 3; PlaceOfError := 320; end; PlaceOfError := 321; inc(BackCount); PlaceOfError := 322; end; ... ошибка на этом шаге setlength(Polypoints, POintCount); |
|||
27
Кирпич
18.11.15
✎
10:36
|
Без отладчика тут фиг разберешься. А какая ошибка то вообще?
|
|||
28
aka AMIGO
18.11.15
✎
10:45
|
про сабжевую функцию много чего есть в яндексе.. Только нажать буковку "Я" справа от топика
|
|||
29
Гёдза
18.11.15
✎
10:48
|
(25) Так это же не связный список, а типичный список на основе массива (arraylist) реализации которых может быть 100500 штук
|
|||
30
Кирпич
18.11.15
✎
10:59
|
Polypoints как определена в этой функции?
вообще, всё что нужно знать про динамический массив - что это указатель и этот указатель меняется после setlength. |
|||
31
Про100Филя
18.11.15
✎
11:00
|
(26) - Значения смотри в отладчике POintCount и где объявленна Polypoints?
Какая версия Делфей? |
|||
32
qeos
18.11.15
✎
11:07
|
(26) да не.. ошибка гдето вкоде.
и да нужна версия. |
|||
33
Кирпич
18.11.15
✎
11:09
|
похоже автор опять ушел на сутки
|
|||
34
Garykom
гуру
18.11.15
✎
11:25
|
(33) думаешь нуна заехать? :)
|
|||
35
Kseniya_
18.11.15
✎
11:37
|
(30) Polypoints: array of TDPOint;
type TDPoint = record X, Y: single; end; |
|||
36
Kseniya_
18.11.15
✎
11:38
|
(33) я здесь, вчера просто уехала раньше
|
|||
37
Garykom
гуру
18.11.15
✎
11:39
|
(35) так размер то этого "array of" где устанавливается?
|
|||
38
Kseniya_
18.11.15
✎
11:41
|
(37) Все время с помощью setlength, когда необходимо менять размер массива. При этом, ломается на setlength не каждый раз при одних и тех же действий пользователя, а рандомно, вполне похоже, что памяти иногда хватает, иногда нет
|
|||
39
Про100Филя
18.11.15
✎
11:44
|
(35) Где объявлена Polypoints: array of TDPOint;?
Ты его случайно ссылкой не передаешь? Delphi 7? И зачем сначала писать в массив, потом его увеличивать? |
|||
40
Garykom
гуру
18.11.15
✎
11:46
|
(38) тогда:
1. попробовать пойти по пути http://www.sql.ru/forum/543676/oshibka-pri-rabote-setlength-procedury 2. не делать каждый раз увеличение массива а либо один раз его сделать большим, с запасом 3. вообще на динамические списки перейти вместо динамического массива |
|||
41
Кирпич
18.11.15
✎
11:46
|
(38) что такое ломается? какая ошибка? и выложи всю функцию хотя бы.
|
|||
42
qeos
18.11.15
✎
11:50
|
generic`и наше фсьо
|
|||
43
Kseniya_
18.11.15
✎
11:51
|
(41) 17.11.2015 13:04:48 - Troads.GetRoadPolygon, Error = 281: Access violation at address 00409B22 in module. Write of address 00000050 (Poly_unit.pas, line 2436, address $7A0319)
|
|||
44
Kseniya_
18.11.15
✎
12:04
|
(40) Возможно сначала попробую такой путь. Спасибо. Там просто массив увеличивается и потом по его размеру идет проверка на его длину, но кол-во можно и в переменную записать. Главное осторожно сделать. В любом случае, в этом ошибка или нет, но нужно заняться оптимизацией, чтобы ничто не кушало больше памяти, чем положено.
|
|||
45
Гёдза
18.11.15
✎
12:09
|
В jave массив увеличивается так:
1. Создается НОВЫЙ массив вдвое больший. 2. Копируется туда значения старого 3. Ссылки на старый убираются (аналогично удалению старого) |
|||
46
Кирпич
18.11.15
✎
12:10
|
(44) кода мы видимо не дождемся. но может проблема совсем в другом месте программы. если у тебя в другом месте программы какой нибудь косяк при работе с динамической памятью, то тебе никакие динамические списки не помогут.
|
|||
47
Кирпич
18.11.15
✎
12:17
|
(45) Ну и в Delphi так же
|
|||
48
Serginio1
18.11.15
✎
12:19
|
(47) Смотря вкакой версии. В 7 там было 40%
|
|||
49
H A D G E H O G s
18.11.15
✎
12:20
|
Автору - попробовать поставить в свойствах проекта, на вкладке "Compiling" галочку "Range checking", пересобрать проект и попробовать воспроизвести ошибку.
|
|||
50
Кирпич
18.11.15
✎
12:22
|
(48) да какая разница сколько процентов. принцип тот же.
|
|||
51
Гёдза
18.11.15
✎
12:22
|
(47) Но здесь то нет нового массива и копирования туда старого. Тут просто увеличение старого
|
|||
52
Гёдза
18.11.15
✎
12:23
|
setlength обычно юзается для УМЕНЬШЕНИЯ длины
|
|||
53
Кирпич
18.11.15
✎
12:25
|
(51) массив автоматом копируется когда делаешь setlength с увеличением
|
|||
54
Кирпич
18.11.15
✎
12:28
|
(52) это ты сейчас придумал?
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |