Класс матрица: ОШИБКА Out of memory - Free Pascal
Формулировка задачи:
Кто поможет наити ошибку ?
синтаксических ошибок нет
но когда пытаюсь создать матрицу выдает ошибку Errcode1: Out of memory
когда делаю
New(mas,create(23,22)); - без проблем
когда показать выдает ошибкув этом фрагменте основной пограммы :
это модуль - в нем реализован класс матрица
procedure showtable(var ns1,ns2:integer; var mas:PMatrix); var i,j: byte; a:single; st:String; qw,qw1:Telem; x,y:word; begin textcolor(white); if (ns1=0) or (ns2=0) then begin clrscr; writeln(nad1); readln; end else begin clrscr; for i:=1 to ns1 do begin writeln; for j:=1 to ns2 do begin { Âûâîä } mas^.get(i,j,qw); if qw<0 then qw:=-qw; Str(trunc(qw),st); mas^.get(i,j,qw1); if (length(st)=3) and (qw1>0) then write('':3); //3 if (length(st)=3) and (qw1<0) then write('':2); //2 if (qw1<0) and (length(st)=2) then write('':3); //3 if (qw1<0) and (length(st)=1) then write('':4); //4 if (qw1>=0) and (length(st)=2) then write('':4); //4 if (qw1>=0) and (length(st)=1) then write('':5); //5 write(qw1:2:3); { if (i=q) and (j=w) then begin textbackground(10); write(mas^[i]^[j]:2:3); textbackground(0); textcolor(15); end else textbackground(blue); } { ÂÛÂÎÄ } end; end; gotoxy(1,1); readln; end; textcolor(15); end;
{$N+} unit MeninMod; interface type TReal=real; TSignedInt=integer; TUnsignedInt=word; TLongSignedInt=longint; TIndex1=TUnSignedInt; TIndex2=TUnSignedInt; TElem=single; PLine=^TLine; TLine=array[1..1] of TElem; PCol=^TCol; TCol=array[1..1] of PLine; PMatrix=^CMatrix; CMatrix=object private Mas:PCol; Low1,High1:TIndex1; Low2,High2:TIndex2; Lines:TUnSignedInt; Cols:TUnSignedInt; Tmasix:TElem; n,m:TUnSignedInt; Procedure Failure(Errnum:TUnSignedInt); { } public constructor Create(ns1,ns2:TIndex2); { } destructor Destroy;{(l1,h1:TIndex1;l2,h2:TIndex2); } procedure Put(i:TIndex1;j:TIndex2;x:Telem); { } procedure Get(i:TIndex1;j:TIndex2; var x:Telem); { } { function GetLow1:TIndex1; function GetLow2:TIndex2; function GetHigh1:TIndex1; function GetHigh2:TIndex2; } function GetLines:TUnSignedInt; function GetCols:TUnSignedInt; end; Implementation {$R-} uses crt; const Selem=SizeOf(Telem); SegmentSize=65520; constructor CMatrix.Create(ns1,ns2:TIndex2); var i: TUnSignedInt; begin if (ns1<0) or (ns2<0) then failure(1) else begin GetMem(mas,ns1*sizeof(PLine)); for i := 1 to ns1 do GetMem(mas^[i],ns2*sizeof(TElem)); end; end; {*********************************************************** function CMatrix.GetLow1:TIndex1; begin GetLow1:=Low1; end; function CMatrix.GetLow2:TIndex2; begin GetLow2:=Low2; end; function CMatrix.GetHigh1:TIndex1; begin GetHigh1:=High1; end; function CMatrix.GetHigh2:TIndex2; begin GetHigh2:=High2; end; } function CMatrix.GetLines:TUnSignedInt; begin GetLines:=Lines; end; function CMatrix.GetCols:TUnSignedInt; begin GetCols:=Cols; end; procedure Cmatrix.Put(i:TIndex1; j:TIndex2; x:Telem); begin if (i<0) or (i>m) then Failure(5) else if (j<0) or (j>n) then Failure(6) else Mas^[i]^[j]:=x; end; procedure CMatrix.Get(i:TIndex1; j:TIndex2; var x:Telem); begin if (i<0) or (i>m) then Failure(7) else if (j<0) or (j>n) then Failure(8) else x:=Mas^[i]^[j]; end; Procedure CMatrix.Failure(Errnum:TUnSignedInt); begin clrscr; writeln('Error : '); case Errnum of 1: Writeln(' No enough memory ..'); 2: Writeln(' Wrong borders ..'); 3: writeln(' Nothing to copy ..'); 4: writeln(' Invalid index of the row ..'); 5: writeln(' Invalid index of the column ..'); end; Halt(1); end; destructor CMatrix.Destroy; var i:TUnSignedInt; begin for i:=1 to Lines do freemem(Mas^[i],longint(cols)*Selem); end; end.
Решение задачи: «Класс матрица: ОШИБКА Out of memory»
textual
Листинг программы
unit matrix; interface uses crt; type TELint=longint; TElem = double; TLine = array[1..maxint div sizeof(TElem)] of TElem; PLine = ^TLine; TCol = array[1..maxint div sizeof(PLine)] of PLine; PCol = ^TCol; PCmatr=^Cmatr; Cmatr=object private Fstr:word; Fstc:word; Fmatr:PCol; procedure F(err:word); public constructor Create(n,m:word); //выделение памяти под матрицу constructor copy(matr:PCmatr); //создание копии матрицы destructor done(); //освобождение памяти, уничтожение матрицы матрицы procedure putelem(i,j:word; elem:TElem); procedure getelem(i,j:word; var x:TElem); function getstr:word; function getstc:word; end; //********************************************************************************************************************************** implementation procedure Cmatr.F(err:word); begin case err of 1 : begin write('Ошибка выделения памяти'); delay(1800); write(' '); end; 2 : begin write('Указаны нулевые индексы'); delay(1800); write(' '); end; 3 : begin write('Указанных индексов в матрице нет'); delay(1800); write(' '); readkey; halt; end; end; end; constructor Cmatr.Create(n,m:word); //returnnilifgrowheapfails := true; var i,j:TELint; error:boolean=true; begin returnnilifgrowheapfails := true; Fstr:=n; Fstc:=m; getmem(Fmatr,Fstr*sizeof(PLine)); //выделяем память под строки if Fmatr<>NIL then begin for j:=1 to Fstr do begin getmem(Fmatr^[j],Fstc*sizeof(TElem));//выделяем память под столбцы if Fmatr^[j]=NIL then //если памяти недостаточно, то аварийный выход из цикла begin F(1); error:=false; break; end; end; if not(error) then for j:=j-1 downto 1 do freemem(Fmatr^[j],Fstc*sizeof(TElem));//освобождаем память end else begin freemem(Fmatr,Fstr*sizeof(PLine)); error:=false; F(1); end; end; //*********************************************************************************************************************************** constructor Cmatr.copy(matr:PCmatr); //returnnilifgrowheapfails := true; var i,j:TELint; begin Create(matr^.Fstr,matr^.Fstc); for i:=1 to Fstr do for j:=1 to Fstc do Fmatr^[i]^[j]:=matr^.Fmatr^[i]^[j] end; //*********************************************************************************************************************************** destructor Cmatr.done(); var i, j: word; need: longint; begin need := longint(Fstc) * sizeof(TElem); {$R-} for i := 1 to Fstr do freeMem(Fmatr^[i], need); need:= longint(Fstr) * sizeof(PLine); freeMem(Fmatr, need); {$R+} end; procedure Cmatr.putelem(i,j:word; elem:TElem); begin if ((i=0) or (j=0)) then f(2) else if ((i>Fstr) or (j>Fstc)) then F(3) else Fmatr^[i]^[j]:=elem; end; procedure Cmatr.getelem(i,j:word;var X:Telem); begin if ((i=0) or (j=0)) then f(2) else if ((i>Fstr) or (j>Fstc)) then F(3) else X:=Fmatr^[i]^[j]; end; function Cmatr.getstr:word; begin getstr:=Fstr; end; function Cmatr.getstc:word; begin getstc:=Fstc; end; end. все робит как надо
Объяснение кода листинга программы
В данном коде представлен класс матрицы для работы с двумерными массивами.
- В первой строке объявлены типы данных, используемые в классе:
- TELint - длинное целое число, используется для представления индексов матрицы;
- TCol - массив указателей на элементы матрицы;
- TLine - массив элементов типа TElem, используется для хранения строк матрицы;
- PCol - указатель на массив TCol;
- PLine - указатель на массив TLine;
- PCmatr - указатель на экземпляр класса Cmatr;
- Cmatr - объект класса, представляющий матрицу.
- В следующих строках определены константы, используемые в классе:
- maxint - максимальное значение для типа данных TELint, используется для вычисления размера памяти, выделяемой под матрицу;
- word - тип данных, используемый для представления слов в Паскале.
- В строке с номером 20 определены поля класса Cmatr:
- Fstr - количество строк в матрице;
- Fstc - количество столбцов в матрице;
- Fmatr - указатель на массив строк матрицы.
- В строке с номером 30 определены методы класса Cmatr:
- F - метод для обработки ошибок при выделении памяти;
- Create - метод для создания экземпляра класса Cmatr;
- copy - метод для копирования матрицы;
- done - метод для освобождения памяти и уничтожения матрицы;
- putelem - метод для добавления элемента в матрицу;
- getelem - метод для получения элемента из матрицы;
- getstr - метод для получения количества строк в матрице;
- getstc - метод для получения количества столбцов в матрице.
- В строке с номером 40 начинается реализация метода Create. Сначала определяется флаг error, который устанавливается в true. Затем выделяется память под строки матрицы и проверяется, успешно ли это было сделано. Если память была выделена успешно, то в цикле выделяется память под столбцы каждой строки. Если при выделении памяти хотя бы для одного столбца возникает ошибка, то значение error устанавливается в false и происходит выход из цикла. Если после завершения цикла значение error остается true, то это означает, что память не была выделена успешно ни для одной строки, и в таком случае метод Create возвращает ошибку.
- В строке с номером 50 начинается реализация метода copy. Сначала вызывается метод Create для создания нового экземпляра класса Cmatr. Затем в цикле копируются элементы из исходной матрицы в новую.
- В строке с номером 60 начинается реализация метода done. Сначала определяется размер памяти, которую занимает матрица. Затем в цикле освобождается память, выделенная под строки и столбцы матрицы.
- В строке с номером 70 начинается реализация метода putelem. Сначала проверяется, являются ли индексы i и j корректными (не равны нулю). Если это так, то проверяется, существуют ли такие индексы в матрице. Если это так, то в матрицу записывается элемент elem.
- В строке с номером 80 начинается реализация метода getelem. Сначала проверяется, являются ли индексы i и j корректными (не больше размера матрицы). Если это так, то возвращается значение элемента, находящегося по указанным индексам.
- В строке с номером 90 начинается реализация метода getstr. Сначала возвращается значение поля Fstr.
- В строке с номером 100 начинается реализация метода getstc. Сначала возвращается значение поля Fstc. Таким образом, данный код представляет собой рабочий класс матрицы, который может выделять память под матрицу, создавать ее копию, заполнять и получать элементы матрицы.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д