Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 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.008 c
1-20588
AlexVM
2003-07-24 11:09
2003.08.07
Как управлять ActionManager ом в runtime


6-20654
Basilio
2003-05-30 09:58
2003.08.07
Проблемы с записью в сокет непосредственно после его открытия


6-20653
BJValentine
2003-05-29 14:16
2003.08.07
Net send


14-20694
vidiv
2003-07-23 12:09
2003.08.07
Предложение для Админов форума.


3-20394
Alex_x
2003-07-16 10:24
2003.08.07
Как в BeforeDelete отменить процес удаления





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский