Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.08.28;
Скачать: [xml.tar.bz2];

Вниз

Access Violation при возврате из функции   Найти похожие ветки 

 
Tihinen   (2005-08-06 01:06) [0]

Не могу понять что не так. Имеется вот такой кусок программы.

type
 TDrawClass = class
 private
   fTarget:TCanvas;
   function SubDrawRoutine(a:integer;b,c,d:Integer;e:integer;f:integer):integer;

 public
   constructor Create(Target:TCanvas);
   destructor Destroy; override;
   function  Draw(DM:TMyMatrix;const DrawCycle:Integer=-1;Var1:Integer =0):Boolean;

// в качестве Target используется Саnvas созданного однажды Bitmap - чтото вроде теневого экрана
constructor TDrawClass.Create(Target:TCanvas);
begin
fTarget:=Target;
end;

destructor TDrawClass.Destroy;
begin
inherited Destroy;
end;

function TDrawClass.SubDrawRoutine(a:integer;b,c,d:Integer;e:integer;f:integer):integer;
begin
//вычисляются Rect1,Rect2,Rect3 исходя из параметров a,b,c,d,e,f
// исходя из них же грузится SourceBmp
//...

fTarget.CopyRect(Rect1,SourceBmp.Canvas,Rect1);
fTarget.CopyRect(Rect2,SourceBmp.Canvas,Rect2);
fTarget.CopyRect(Rect3,SourceBmp.Canvas,Rect3);
end;

function TDrawClass.Draw(DM:TMyMatrix;const DrawCycle:Integer=-1;Var1:Integer =0):Boolean;
begin
try
//
..
//циклически вызывается TDrawClass.SubDrawRoutine
//
Result:=True;
fTarget.Draw(0,0,ResX.GetBitmap("Top"));
fTarget.Draw(0,450,ResX.GetBitmap("Bottom"));
except
MessageBox(0,"1","1",0);
end;
end;

//на основной форме вызывается по таймеру Draw;
//...
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
begin
//...
try
MyDrawClass.Draw(DM,DrawCycle);
except
MessageBox(0,"2","2",0);
end;
//...
end;

происходит срабатывание второго эксепшна и вызывается второй мессаджбокс,
то есть Access Violation возникает на возврате из функции Draw, а не внутри нее.
Сопственно изза чего это может происходить? Причем возникает он совсем с непонятной периодичностью, то возникает то нет.
Но всегда одинаковый "по адресу 00000013 чтение адреса FFFFFFFF"
параметр DM: TMyMatrix = array [1..3,1..5] of integer является свойством третьего класса.
Мне вот кажется что дело тут вовсе не в рисовании, а в том что возврат из функции Draw осуществляется както коряво.
Памажите.


 
DrPass ©   (2005-08-06 01:32) [1]


> то есть Access Violation возникает на возврате из функции
> Draw,

Точно ли на возврате? А может, перед вызовом? Корректно ли инициализирован MyDrawClass? Или еще что?


 
Tihinen   (2005-08-06 01:53) [2]

Точно на возврате.
я вот ввел глобальную переменную DebugStr:String;
и функция Draw выглядит примерно так...
function TDrawClass.Draw;
begin
try
//
..
DebugStr:="1";
//..
DebugStr:="2";
//..
Result:=True;
DebugStr:="12";
fTarget.Draw(0,0,ResX.GetBitmap("Top"));
DebugStr:="13";
fTarget.Draw(0,450,ResX.GetBitmap("Bottom"));
DebugStr:="DrawExit";
except
MessageBox(0,"1","1",0);
end;
end;

и перед вызовом Draw - тоже самое
DebugStr:="0";
Draw;
DebugStr:="AfterExit";

и когда происходит экспшн - DebugStr всегда DrawExit, то есть последняя строчка функции Draw всегда выполняется. Такая вот штука :-/


 
Mx ©   (2005-08-06 02:14) [3]

А я вот подумал: с учетом того, что raise внутри except-блока в TDrawClass.Draw нет, то второе исключение может возникнуть лишь если внутри этого блока какая-то ошибка. Или, действительно, ошибка на самом возврате, но я себе это слабо представляю.

А нельзя ли привести весь код TDrawClass.Draw? Какого вида переменные в нем используются?


 
Джо ©   (2005-08-06 02:17) [4]


>  Или, действительно, ошибка на самом возврате, но я себе
> это слабо представляю.

Представить не сложно ;) Это может быть, например, из-за того, что внутри процедуры запорчен стэк.


 
Mx ©   (2005-08-06 02:20) [5]


> Джо ©   (06.08.05 02:17) [4]

"Сложно" для приведенного варианта, потому и запросил "весь код".

P.S. Блин, опять два часа ночи, а я всё не сплю. А ведь каждый день обещаю себе лечь вовремя и выспаться...


 
Tihinen   (2005-08-06 02:28) [6]

да код привести несложно... просто врядли это чтото даст. Я наоборот пытаюсь максимально упростить картину для восприятия.

все именно вот так :

function Draw;
begin
try
 //...
 DebugStr:="DrawExit";
except
MessageBox(0,"1","1",0);
end;
end;

в теле программы
//....
try
DebugStr:="BeforeDraw";
Draw();
DebugStr:="AfterDraw";
except
MessageBox(0,"2","2",0);
end;
//....

На момент появления эксепшна DebugStr="DrawExit" !!!
Ну и если это чтото даст то вот эта функция. У меня были сомнения именно в передаче параметров в нее. Я бы предложил что это какой то системный сбой вообще не связанный с этим, поскольку используется DirectX и еще и Flash, но меня смущает, что происходит он всегда с функцией именно этой.

function  TAniDrum.Draw(DM:TDrumMatrix;const Cycle:Integer; FlashCount:integer):Boolean;
var i:integer;
   Upp,Mid,Btm:Integer;
   Shift:Integer;
begin
Result:=False;
try
for i:=1 to 5 do
 begin
 if (Cycle>0) and (Cycle<RotateCycles[i]) then
   begin
   Upp:=-((Cycle mod 5)+1);
   Mid:=Upp;
   Btm:=Upp;
   Shift:=0;
   end
 else
   begin
   Upp:=DM[1,i];
   Mid:=DM[2,i];
   Btm:=DM[3,i];
   if Cycle=RotateCycles[i] then
       Shift:=10
   else
       Shift:=0;
   end;
 Lop:="6";
 FlashCount:=FlashCount-GenerateDrum(i-1,Upp,Mid,Btm,Shift,FlashCount);
 Lop:="7";
 end; //for i:=1 to 5 do
Result:=True;
fTarget.Draw(0,0,ResX.GetBitmap("Top"));
fTarget.Draw(0,450,ResX.GetBitmap("Bottom"));
if (Cycle>RotateCycles[5]+1) or (Cycle=0) then Result:=False;
Lop:="DrawExit";
except
MessageBox(0,"1","1",0)
end;
end;


 
Tihinen   (2005-08-06 02:32) [7]

А как вот можно испортить стек? Вот выделенная и неочищенная память эт я понимаю. Но выделения памяти нигде я сопсна внутри функции не делаю.


 
Джо ©   (2005-08-06 02:44) [8]

Может быть все что угодно. Что, например, делает GenerateDrum? Что за массив RotateCycles - где объявлен и инициализирован? Что за ResX с загадочным методом GetBitmap? Почему GetBitmap вызывается, а, возможно, выделенный ресурс нигде не освобождается?
Одни вопросы...


 
Джо ©   (2005-08-06 02:44) [9]

Пробуй локализовать.


 
Tihinen   (2005-08-06 02:54) [10]

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

SourceBmp:=ResX.GetBitmap("Rotate");
fTarget.CopyRect(RectN,SourceBmp.Canvas,RectN);

дык вот нащщот ResX.GetBitmap;

есть вот такой класс

type
 TResourceX = class
 private
   RS:TResourceStream;
   BMPList:TList;
   NameList:TStringList;
 public
   constructor Create;
   destructor Destroy; override;
   procedure AddJpeg(const ResName: string);
   procedure AddGif(const ResName: string);
   procedure AddBmp(const ResName: string);
   function  GetBitmap(const ResName: string):TBitmap;
end;

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

function TResourceX.GetBitmap(const ResName: string):TBitmap;
begin
Result:=TBitmap(BMPList[Namelist.IndexOf(UpperCase(ResName))]);
end;

procedure TResourceX.AddJpeg(const ResName: string);
var TmpImage:TJpegImage;
   Bmp:TBitmap;
begin
RS := TResourceStream.Create(0, ResName, "IMAGE");
TmpImage:=TJpegImage.Create;
TmpImage.LoadFromStream(RS);
TmpImage.DIBNeeded;
Bmp:=TBitmap.Create;
Bmp.Assign(TmpImage);
BMPList.Add(Bmp);
TmpImage.Free;
RS.Free;
NameList.Add(UpperCase(ResName));
end;

Ну и RotateCycles вот.

const RotateCycles: array [1..5] of integer =(8,16,24,32,40);

:)

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


 
Tihinen   (2005-08-06 02:57) [11]

Джо. Пробуй локализовать.
Что локализовывать?


 
Джо ©   (2005-08-06 03:02) [12]


> Мне хотелось бы услышать про испорченный стек. Меня вот
> данный вопрос интересует

А что тут интересного. Ну, вот самый простой пример:

procedure Proc;
var
 I: Integer;
 Arr: array [0..2] of Integer;
begin
 for I := 0 to 3 do
 begin
   Arr[I] := 10;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 Proc
end;

Нажмешь на кнопку и получишь AV. Потому что массив расположен в стэке, а ты вышел за пределы массива (for I := 0 to 3), таким образом запортив стэк. Соответственно, запортив то, что в нем лежало, возможно, и адрес возврата из процедуры.


 
Джо ©   (2005-08-06 03:05) [13]


>  [11] Tihinen   (06.08.05 02:57)
> Джо. Пробуй локализовать.
> Что локализовывать?

Локализовать проблему. То есть, найти минимальное количество кода, при котором нет проблем. Затем потихоньку начинай добавлять (раскомментировать) остальные строки, наблюдая, когда проблема появится. Возможно, поможет пошаговая отладка с заходом во все процедуры (F7) с включенной опцией компилятора Use debug DCU"s.


 
Джо ©   (2005-08-06 03:13) [14]


> [13] Джо ©   (06.08.05 03:05)

Коряво и неверно выразился.
Закомментируй все тело процедуры, при выходе из которой вылетает AV. Затем, начинай раскомментировать по одной строчку, каждый раз компилируя и запуская. Когда появится AV, будешь знать, из-за какой строчки. Ну, ты меня понял, надеюсь :)


 
Anatoly Podgoretsky ©   (2005-08-06 11:55) [15]

Tihinen   (06.08.05 02:28) [6]
function Draw;

Не обманывай, это просто не откомпилируется и ни о каком AV говорить и не приходится.


 
Tihinen   (2005-08-08 21:23) [16]

К чему бы мне обманывать?

и с какой это радости не откомпилируецца то?

type TDrawClass = class



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

Форум: "Основная";
Текущий архив: 2005.08.28;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.038 c
1-1123392246
Antonn
2005-08-07 09:24
2005.08.28
перемещение контрола за всю клиентскую область


1-1123154318
dreamse
2005-08-04 15:18
2005.08.28
Как в одном Listwiew e работать с двумя разными imageList ?


4-1121231982
Jupiter
2005-07-13 09:19
2005.08.28
Архивация с помощью ARJ


9-1115531873
Kobik
2005-05-08 09:57
2005.08.28
DXSound 8


1-1123491917
Alx2
2005-08-08 13:05
2005.08.28
D6 не хочет компилировать следущий код:





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский