Имя: Пароль:
IT
 
Делфи. Не работает 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) это ты сейчас придумал?
Кaк может человек ожидaть, что его мольбaм о снисхождении ответит тот, кто превыше, когдa сaм он откaзывaет в милосердии тем, кто ниже его? Петр Трубецкой