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

Вниз

Сижу в глубокой отладке второй день   Найти похожие ветки 

 
Эдуард   (2003-07-22 21:28) [0]

Дело вот в чем.

есть массив динамический Boxes: array of TBox;Есть указатель типа Current: ^TBox;
Current := @Boxes[High(Boxes)];
при обращении к Current^ выдается ошибка Access Violation
сделал так:
var Box: TBox;
Box := Boxes[High(Boxes)];
Current := @Box;

все прошло, но потом начал дописывать программу и опять выскочила таже ошибка в том же месте мол Current^ не существует.

Я думаю загвоздка где-то здесь, так как динамический массив это ^array of TBox; т.е. это тоже указатель. А как решить проблему незнаю.

Мастреа подскажите пожалуйста.


 
default ©   (2003-07-22 21:39) [1]


var
Current: TBox;
Boxes: Array of TBox;
begin
SetLength(Boxes, число_элементов_массива);
Current := Boxes[High(Boxes)];
// ...
SetLength(Boxes, 0);
end;

и никакие указатели тут не нужны


 
Романов Р.В. ©   (2003-07-22 21:41) [2]

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


 
default ©   (2003-07-22 21:41) [3]

а вообще чужно = сам говоришь массив динамический, а сам не выделяешь под него память хе


 
default ©   (2003-07-22 21:44) [4]

динамический массив - это не указатель


 
Романов Р.В. ©   (2003-07-22 21:48) [5]


> default © (22.07.03 21:44)
> динамический массив - это не указатель


То что имел в виду автор, как раз и есть указатель


 
default ©   (2003-07-22 22:17) [6]

я не про это
я про то что, "так как динамический массив это ^array of TBox" -
бред


 
Эдуард   (2003-07-22 22:36) [7]


> default © (22.07.03 21:41)
> а вообще чужно = сам говоришь массив динамический, а сам
> не выделяешь под него память хе


SetLength(Boxes, 1);
по-моему выделяет память.


> Романов Р.В. © (22.07.03 21:41)
> При увеличении размера массива для него выделяется новый
> блок памяти, так что адрес элемента массива может оказаться
> недействительным


А как обойти это?


 
default ©   (2003-07-22 22:52) [8]

я вообще не понимаю, что написал Романов Р.В.
и тебе не советую это брать в голову


 
Романов Р.В. ©   (2003-07-22 22:53) [9]


> А как обойти это?

Пересмотреть логику программы.
1. Не использовать в программе адрес элемента динамического массива
2. Не изменять его размер


 
default ©   (2003-07-22 22:56) [10]

напиши что тебе нужно сделать
может динмассив вообще не нужен


 
Романов Р.В. ©   (2003-07-22 23:10) [11]


> default © (22.07.03 22:52)


system.pas

procedure DynArraySetLength(var a: Pointer; typeInfo: PDynArrayTypeInfo; dimCnt: Longint; lengthVec: PLongint);
var
i: Integer;
newLength, oldLength, minLength: Longint;
elSize: Longint;
neededSize: Longint;
p, pp: Pointer;
begin
p := a;

// Fetch the new length of the array in this dimension, and the old length
newLength := PLongint(lengthVec)^;
if newLength <= 0 then
begin
if newLength < 0 then
Error(reRangeError);
DynArrayClear(a, typeInfo);
exit;
end;

oldLength := 0;
if p <> nil then
begin
Dec(PLongint(p));
oldLength := PLongint(p)^;
Dec(PLongint(p));
end;

// Calculate the needed size of the heap object
Inc(PChar(typeInfo), Length(typeInfo.name));
elSize := typeInfo.elSize;
if typeInfo.elType <> nil then
typeInfo := typeInfo.elType^
else
typeInfo := nil;
neededSize := newLength*elSize;
if neededSize div newLength <> elSize then
Error(reRangeError);
Inc(neededSize, Sizeof(Longint)*2);

// If the heap object isn"t shared (ref count = 1), just resize it. Otherwise, we make a copy
if (p = nil) or (PLongint(p)^ = 1) then
begin
pp := p;
if (newLength < oldLength) and (typeInfo <> nil) then
FinalizeArray(PChar(p) + Sizeof(Longint)*2 + newLength*elSize, typeInfo, oldLength - newLength);
ReallocMem(pp, neededSize);
p := pp;
end
else
begin
Dec(PLongint(p)^);
GetMem(p, neededSize);
minLength := oldLength;
if minLength > newLength then
minLength := newLength;
if typeInfo <> nil then
begin
FillChar((PChar(p) + Sizeof(Longint)*2)^, minLength*elSize, 0);
CopyArray(PChar(p) + Sizeof(Longint)*2, a, typeInfo, minLength)
end
else
Move(PChar(a)^, (PChar(p) + Sizeof(Longint)*2)^, minLength*elSize);
end;

// The heap object will now have a ref count of 1 and the new length
PLongint(p)^ := 1;
Inc(PLongint(p));
PLongint(p)^ := newLength;
Inc(PLongint(p));

// Set the new memory to all zero bits
FillChar((PChar(p) + elSize * oldLength)^, elSize * (newLength - oldLength), 0);

// Take care of the inner dimensions, if any
if dimCnt > 1 then
begin
Inc(lengthVec);
Dec(dimCnt);
for i := 0 to newLength-1 do
DynArraySetLength(PPointerArray(p)[i], typeInfo, dimCnt, lengthVec);
end;
a := p;
end;


 
Эдуард   (2003-07-22 23:50) [12]

Всем спасибо, проблема решина.
Романов В.В. дал очень ценное указание, которое и спасло всю ситуацию.


> При увеличении размера массива для него выделяется новый
> блок памяти, так что адрес элемента массива может оказаться
> недействительным

Именно это помогло.
было так:
var
Box: TBox;
for i:=0 to 6 do
begin
SetLength(Boxes, i+1);
Boxes[High(Boxes)] := TBox.Create;
Box := Boxes[High(Boxes)];
Current[i] := @Box;
end;


Стало так:
for i:=0 to 6 do
begin
SetLength(Boxes, i+1);
Boxes[High(Boxes)] := TBox.Create;
end;
for i:=0 to 6 do
Current[i] := @Boxes[i];


т.е. действительно дело в изменении размера массива.

Всем еще раз спасибо.


 
Романов Р.В. ©   (2003-07-22 23:57) [13]

А что сразу SetLength(Boxes, 6) нельзя сделать?


 
Beginner3000   (2003-07-23 00:14) [14]

Чёто я не пойму
для такой реализации указатели не нужны были
поэлементно и так перегнать можно было
а через указатели быстрее целиком и сразу указателями на первый элемент массива
без цикла


 
Beginner3000   (2003-07-23 00:39) [15]

Ой
Почему мы здесь?


 
panov ©   (2003-07-23 00:47) [16]

>Beginner3000 (23.07.03 00:39)
Ой
Почему мы здесь?


Потому что тема вопроса должна быть информативной.


 
Beginner3000   (2003-07-23 00:50) [17]

Но тело-то ничё так
мясистое
суров, батенька


 
Anatoly Podgoretsky ©   (2003-07-23 01:19) [18]

Beginner3000 (23.07.03 00:39)
Полагодарить надо, что не удали, видимо монетка не так упала.

Для непонятливых
если монетка упала орлом, то переместить в правильную ветку
если монетка упала орлом, то удалить
а если зависла в воздухе, то в потрепаться


 
Beginner3000   (2003-07-23 01:30) [19]

неправильный case
два орла
а вместе с темой показывают ещё кусок тела, так что информативности по
данной ветке хватало
но, конечно, хозяин - барин


 
Fenik ©   (2003-07-23 01:42) [20]

Действительно зря переместили.


 
panov ©   (2003-07-23 02:20) [21]

>Beginner3000 (23.07.03 01:30)
неправильный case
два орла
а вместе с темой показывают ещё кусок тела, так что информативности по
данной ветке хватало
но, конечно, хозяин - барин


Тело сообщения лишь раскрытие темы.

В теме должно быть видно, о чем в ветке идет разговор.


 
SergP ©   (2003-07-23 05:03) [22]


> Anatoly Podgoretsky © (23.07.03 01:19)
> Beginner3000 (23.07.03 00:39)
> Полагодарить надо, что не удали, видимо монетка не так упала.
>
> Для непонятливых
> если монетка упала орлом, то переместить в правильную ветку
> если монетка упала орлом, то удалить
> а если зависла в воздухе, то в потрепаться


Хм... Действительно... А то я долго думал но так и не смог почему одни ветки перемещаются в "потрепаться", другие удаляются а третьи блокируются.
Спасибо что просветили...


 
Anatoly Podgoretsky ©   (2003-07-23 07:53) [23]

Для публикации сообщения надо заполнить форму, если у человека нет сил это сделать в соотвествии с уккзанными полями, то редакция совсем не обязана публиковать это сообщение, разве что по решению суда. Можно написать на заборе, там не надо форму заполнятью


 
Alex Konshin ©   (2003-07-23 07:58) [24]

Помимо ситуации увеличения массива, еще не забудь, что дин.массив имеет счетчик ссылок.
При выходе за границы области видимости счетчик ссылок декрементируется, и если он обнулился, то память, занимаемая массивом освобождается. При работе с такого рода указателями, как у тебя, очень легко нарваться на ситуацию, когда указатель становится неактуальным.



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

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

Наверх




Память: 0.53 MB
Время: 0.013 c
14-20775
dataMaster
2003-07-21 16:44
2003.08.07
Вложить файл в почтовую программу, уст. по-умолчанию


14-20784
Gooz
2003-07-22 09:33
2003.08.07
Глюки


3-20400
Silver_
2003-07-15 17:11
2003.08.07
ORDER BY (GROUP BY) :MyField


4-20866
fav
2003-06-03 20:41
2003.08.07
подобие


1-20608
alenka
2003-07-24 13:04
2003.08.07
Диаграмма в Excel