Вниз
Скачать: CL | DM;

Динамические массивы и SetLength   Найти похожие ветки 

← →
boband   (2003-03-12 09:45) [0]

При использовании процедуры SetLength возникает ошибка access violation. При чем в 99 случаях все отрабатывает нормально, а в 100-м такая проблема. Подскажите в чем прикол, пожалуйста!

Цитата из исходника:
type
PMyColl=^TMyColl
TMyColl=record
Support:integer;
Coll: array of integer;
end;
...
var
Coll:PMyColl; lngt:integer;
...
new(Coll);
Coll^.Support:=15;
SetLength(Coll^.Coll, lngt);//Вот здесь и возникает проблема!!!


← →
KpeHgeJIb   (2003-03-12 10:07) [1]

Когда ты создаеш переменную Cool для нее выделяется количество памяти которое она занимает, НО когда это происходит, поле Cool^.cool пусто и занимает мало памяти, при увеличении его длинны ты вылазиш за пределы выделеной памяти для переменной Cool и получаеш access violation.


← →
NailS ©   (2003-03-12 10:07) [2]


> При чем в 99 случаях все отрабатывает нормально, а в 100-м
> такая проблема.

Терзает смутное сомнение, что собака порылась в другом месте (в работе с Coll). Память не течет случаем?
Да и кода бы побольше не помешало.


← →
Fredericco ©   (2003-03-12 10:14) [3]

Проверь значение lngt во всех ста случаях и напиши о результатах.


← →
Владислав ©   (2003-03-12 12:02) [4]

Создается впечатление, что это маленькая выдержка из кода...
Перед этим: SetLength(Coll^.Coll, lngt); Поставь следующее:
Assert(Coll <> nil, "Coll равен nil");
А перед этим: new(Coll); следующее:
Coll = nil;
И погоняй программу, пока 100 случай не настанет.
Ну и еще много разных способов есть...


← →
Serginio   (2003-03-12 12:35) [5]

new(Coll);
Pointer(Coll^.Support):=nil;
Coll^.Support:=15;
Суть в том, что при выделении памяти данные не обнуляются. А компилятор при присвоении проверяет старую ссылку и если она не равна nil пытается вызвать у динамического массива по этому адресу уменьшение количества ссылок, а та как его не существует вызывается исключение.


← →
Владислав ©   (2003-03-12 13:49) [6]

> Serginio (12.03.03 12:35)

"Pointer(Coll^.Support):=nil;
Coll^.Support:=15;"

Что то я в смысл "не въехал".
Это зачем делать? Да и Support вообще то integer.
Может проще тогда так:
Coll^.Support:=0;
Coll^.Support:=15;

???


← →
icWasya ©   (2003-03-12 14:11) [7]

в смысле
new(Coll);
Pointer(Coll^. Coll):=nil;
Coll^.Support:=15;


← →
Владислав ©   (2003-03-12 14:22) [8]

> icWasya © (12.03.03 14:11)
А так?
new(Coll);
Coll^.Coll:=nil;
Coll^.Support:=15;
:)


← →
PVOzerski ©   (2003-03-12 14:33) [9]

Я бы сразу после new(Coll) "забивал нулями" Coll^.Coll. Например, так:
new(Coll);
FillChar(Coll^.Coll,sizeof(Coll)-sizeof(Coll^.Support),0);

Тогда бы последующий SetLenght гарантированно не получал бы информации о якобы уже выделенной под "тело" массива памяти.


← →
Serginio   (2003-03-12 15:57) [10]

Виноват
...
new(Coll);
Coll^.Support:=15;// или FillChar(Coll^,SizeOf(TMyColl),0);
Pointer(Coll^.Coll):=0;
SetLength(Coll^.Coll, lngt);//Вот здесь и возникает


← →
boband   (2003-03-12 22:22) [11]

Спасибо за советы. Мысль о том, что нужно обнулять указатель на динамический массив здравая, но в моем случае к сожалению не работает. Сработала такая фиговина:
new(Coll);
Coll^.Support:=15;
if Coll^.Support=11 then ShowMessage("1")
else ShowMessage("2")
SetLength(Coll^.Coll, lngt);
Правда сами понимаете такое решение никуда не годиться :-(.



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

Скачать: CL | DM;



Память: 0.47 MB
Время: 0.012 c
8-76537
Dimitri
2002-12-08 22:01
2003.03.24
MPEG-1 video


3-76328
Ocean
2003-03-03 11:17
2003.03.24
AdoQuery1.ExecSQL вызывает ошибку kernel32 (WinME)


3-76309
Casperr
2003-03-05 10:04
2003.03.24
Interbase


8-76527
ДокКир
2002-12-14 15:18
2003.03.24
Графика


14-76621
Delirium^.Tremens
2003-03-05 10:29
2003.03.24
Доброе утро, злая бабушка




   Наверх