ПредишенСледващото

Въпросът за разпределяне на памет за динамични масиви.

На следващото разпределение на паметта на динамичния масив:

Типове TArrayOfDouble = масив от двойно;
VAR ArrayRunEvolutionFits: масив от TArrayOfDouble;
...
SetLength (ArrayRunEvolutionFits, NRun);

Debugger прием Уведомление
Проект ProjectPDB.exe вдигна изключение клас EAccessViolation с "нарушаване на достъпа на адрес 00405F13 в модул" съобщение Project.exe ". Прочетете на адрес 00000003 ". Процес спря. Използвайте Стъпка или Изпълни, за да продължите.

Проектът е съставен и програмата работи, докато не бъде намерен в изпълнение на посочения по-горе ред. Процедури не са свързани с даден масив е също все още работят.

Грешката започнаха да се появяват, след като до Добавяне нова динамика масив (други), които от своя страна работи. След премахването на грешката вече не се случи.

Програмата е написана на Delphi 7 среда и е предназначен за изследователски цели в областта на изследване на структурата на белтъчните молекули. Проектът на заповедта от 20 единици, използва само стандартни компоненти за оказване и OpenGL molukul. Тъй като набори от данни в предварително разрешаване не са известни, ние използваме динамични масиви. Сами масиви по обем не превишава 50 000 тип двойно.

На определен етап вече се е случвало подобно грешки в програмата, Project Options \ Линкер Макс stackzize увеличение до $ 01000000 е решила проблема.

Възможно ли е да се реши този проблем в момента? Може би има грешка на разпределение на паметта; Може би има инструменти, за да ви помогне да следите на разпределение на паметта?

Друга възможност, която мисля, че, за да се заменят някои структури от типа масиви TList. с цел да се облекчи стека. Но дали това ще бъде решение?

Следвайте коментарите към този въпрос чрез RSS

Дмитрий Shatalov
Причина за грешката - банална излиза извън масива, което възниква
дължи на неправилно сравнение на реалните числа.

Ако сложите брояч във всеки цикъл ще видите, че
- в първия цикъл сте просто "късмет" - там са 4000 д-ните и 4000 обаждания до масива.
Това е така, защото в състоянието, докато ZD<=40 do begin равенство zd=40 не отрабатывается.
- във втория цикъл вас "късмет" - там се добавя още една 1000 е-ING и
след това в 1001 жалба до масива. Това е така, защото в състоянието, докато ZD<=50 do begin
равенство е изпълнено ZD = 50 и следователно се оказва на
работа по => изход на масива.

Също така, ако можете да зададете броя на е-ING масив е по-добре
го направя веднага.

Добър ден. Въпросът, разбира се, старите, но аз имам същия voznakla неизвестна грешка. Когато не може - не е ясно. Програмата използва динамичен масив:

процедура createpart;
конст da_len = 12;
Var
profZall: масив от масив от двойно;
ч: двойно; // нарастване на надлъжната координира
Вр, Vrmin: двойно; // контур и намалена скорост на рязане контур
j_int: Longword; // увеличение на масива да се запълни
ZD, XD: двойно; // настоящите подробности позиция

процедура addpoint (Z, X, V: двойно); // запълни краен елемент на масива
Var I: longword;
започвам
profZall [0, j_int]: = 0; // запълни времето до нулеви стойности
profZall [1, j_int]: = Z;
profZall [2, j_int]: = X;
profZall [3, j_int]: = V;
защото: = 4 (da_len- 1) направи profZall [Ь, j_int]: = 0; // нула стойности запълнят останалите
Inc (j_int);
приключи;

j_int: = 0;
ZD: = 0;
// SetLength (profZall, da_len, 500000);

// хоризонтална права част 40 мм
SetLength (profZall, da_len, кръг (40 / ч)); // броя на електронна поща, в същата 4000
докато ZD<= 40 do begin
XD: = 50;
addpoint (ZD, XD, VR);
ZD: = ZD + Н;
приключи;

// част от една четвърт кръг - отидете заедно на радиуса
SetLength (profZall, da_len, j_int + кръг (50 / Н 40 / ч)); // броя на електронна поща, в същата 5000
докато ZD<= 50 do begin
XD: = 60 -roundto (SQRT (пл (10) -sqr (zd- 40)) - 6);
addpoint (ZD, XD, Vrmin);
ZD: = ZD + Н;
приключи;

// раздел осем кръга - преминаването на радиуса
SetLength (profZall, da_len, j_int- 1 + кръг (130 / Н 50 / ч)); // след това трябва да бъде равна на 13 000, но има eksepshn

j_int: = j_int; // + отстраняване на грешки
приключи;

Какво е интересно, ако pokoldovat и добавяне на различни изчислителни боклук, всичко може да свърши работа. И все пак, задачата е със сигурност на голям брой елементи (50 000) са преглътна, но eksepshn все още там на същото място.
Друг много интересен код поведение, ако процедурата пъхна в приложение за конзолата. Нещо като възлагане ролки, но пропуска на j_int линия: = j_int; и лети eksepshn операция InvalidFloatingPointer. Присвояване на масив от нула не помага. Като цяло, всички проблеми.
Да, развитие на околната среда D7

Резултатът е разтвор. съвсем неочаквано, проблемът е решен (постоянно или само за момента) призовава SetLength функции пермутация:

в паметта на източник разпределени за динамични масиви 3:
.
SetLength (ArrayRunEvolution, NRun);
SetLength (ArrayRunEvolutionFits, NRun);
SetLength (ArrayRunEvolutionBestFits, NRun);
.
EAccessViolation е възникнала грешка във втория ред за ArrayRunEvolutionFits. В хода на решаване на кода за проблем беше променена на няколко места, дадени съвети за използването на 777 Low (), High (). Но напредъкът все още е грешка в програмата, настъпили в едно и също място.

Между другото, идеята за промяна на реда на разпределение на паметта. Грешка изчезнали при първите два реда са пренаредени.

Пренареждане на редовете в първоначалното положение да EAccessViolation не води!

За съжаление, сега не е останало версия на проекта, за да се провалят. EAccessViolation върне обратно неуспешна. Надяваме се, че грешката е по вина на компилатора Делфи, а не и на неправилното използване на динамични данни.

MBO. погледнете кода:

за Ирун: = 1 до nRun започвайте
...
ReadRunEvolution (ArrayRunEvolution [Irun-1]);
...
приключи;

1. Тук са всички верни.
2. Програмата не се отнася за прилагането на тази линия, докато извеждате грешка
3. Опцията "Range проверка" е включен, и би било грешка, ако това станало грешка в компилацията
4. преди това място (Грешки започнаха да се появяват, след като на следващия да се добавят нови динамични масиви. С тяхна грешка отстраняване престава да се случи).
5. много подобен каза Антон памет Zaparyvaniya. Но как да го хване? Debug се опитва да използва за идентифициране на източника на грешка

> За Irun: = 1 до nRun
Това е мястото, където кучето започна да рови.
Динамични масиви са номерирани от нула.

Вярвам, че тези места в повече от една програма.
Така че какво да кажем за ниско Висшия съвет на много не на място.

Благодаря на всички ви за вашите отговори.

Антон. Благодаря за изясняването на Zaparyvaniya памет. Много подобна на тази грешка и вероятно не zaparyvanie свързано с редица който се появява нарушение Access. Отново, подобно положение вече е изпълнено, но източникът на грешката, за съжаление, не е установена. В първия случай, на удължения комин и това помогна, но през втората оптимизиран код, изтрийте нежелан динамична структура и програмата е напълно заслужи. След това с впечатлението, че не е достатъчно стак.

Матвей. Благодаря за линка, за да acedutils и напомняне за Кнут.

MBO. Ето и Кодекса за подробности:

Типове TArrayOfDouble = масив от двойно;
VAR ArrayRunEvolutionFits: масив от TArrayOfDouble;
...
SetLength (ArrayRunEvolutionFits, NRun);
...
за Ирун: = 1 до nRun започвайте
...
ReadRunEvolution (ArrayRunEvolution [Irun-1]);
...
приключи;

// функция където ReadRunEvolution difinirana като

функция ReadRunEvolution (Var Подходящ: TArrayOfDouble);

// и в паметта й се разпределя към второто ниво.

грешката е вероятно да се случи по-рано, и се появява само в реда. Отново, имайте предвид, че веднъж, ако програмата не използва тази функция, да извършва други дейности, а след това тя работи, грешката не се случи.

Zaparyvanie памет - това е, когато определена част от паметта, че нещо не е писано да заобиколи процедурите, които го vydeleli и носят отговорност за него. В резултат на това, последователност данни hrangyaschihsya разбити там, което може да доведе до множество грешки при последващи операции с паметта.

Друга възможност, която мисля, че, за да се заменят някои структури от типа масиви TList, за да се разтоварят стека. Но дали това ще бъде решение?
Когато измерение на 50,000 елементи са дървесните структури, за да бъдат много ефективни. Алгоритми, причини и математически изчисления на теоретичната скорост на даден Кнут в 6 глава на третия том. И така, за начало, можете да погледнете acedutils.

ype TArrayOfDouble = масив от двойно;
VAR ArrayRunEvolutionFits: масив от TArrayOfDouble;
...
SetLength (ArrayRunEvolutionFits, NRun);

Можете да видите, че peremennaya- двумерен масив, и SetLength прави само за първото измерване.
Не се разпределят самите масиви памет забравени от второ ниво?

Свързани статии

Подкрепете проекта - споделете линка, благодаря!