Форум: "Потрепаться";
Текущий архив: 2003.08.07;
Скачать: [xml.tar.bz2];
ВнизСижу в глубокой отладке второй день Найти похожие ветки
← →
Эдуард (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;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.009 c