Помощь - Поиск - Пользователи - Календарь
Полная версия: Freemem
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
ангел
Ошибка у меня возникает при вызове этой процедуры...
Либо указатель пустой или число освобождамых байтов выходит за границы кучи ???
вот код:

procedure Push(E:ElementType;var S:Stack);
var
P:pStackElem;
begin
	 P:=new(pStackElem);
	 GetMem(P^.Elem,SizeOf(ElementType));
	 Move(E,P^.Elem,SizeOf(ElementType));
	 P^.Next:=S.Top;
	 S.Top:=P;
	 S.Size:=S.Size+Sizeof(ElementType)+SizeOf(pStackElem)*2+SizeOf(Pointer);
end;

procedure Pop(S:Stack;var E:ElementType);
var top:pStackElem;
begin
	 if S.Top<>nil then
	 begin
	 Move(S.Top^.Elem,E,SizeOf(ElementType));
	 top:=S.Top^.Next;
		 FreeMem(S.Top^.Elem,SizeOf(ElementType));{Вот здесь и возникает ОШИБКА!!!}
	 dispose(S.Top);
	 S.Top:=top;
	 S.Size:=S.Size-Sizeof(ElementType)-SizeOf(pStackElem)*2-SizeOf(Pointer);
	 end
end;

Гость
дополнение:
pStackElem = ^StackElem;
	pElement = ^Element;
	StackElem = record
			  Elem:Pointer;
			  Next:pStackElem;
			  end;

	Stack = record
		  Top: pStackElem;
		  Size: Integer;
		  end;

	Element = record
			data:byte;
			end;
	ElementType = Element;
ангел
Вроде бы все так делаю:
сколько выделил места в памяти под указатель - столько и освобождаю:

...
GetMem(P^.Elem,SizeOf(ElementType));
...


...
FreeMem(S.Top^.Elem,SizeOf(ElementType));
...


Lapp
Ты в операторе Move используешь указатель вместо самой величины. Этим самым ты портишь пойнтер.
procedure Push(E:Element;var S:Stack);
var
  P:pStackElem;
begin
  P:=new(pStackElem);
  GetMem(P^.Elem,SizeOf(Element));
  Move(E,P^.Elem^,SizeOf(Element));  {было Move(E,P^.Elem,SizeOf(ElementType));}
  P^.Next:=S.Top;
  S.Top:=P;
  S.Size:=S.Size+Sizeof(Element)+SizeOf(pStackElem)*2+SizeOf(Pointer);
end;

procedure Pop(S:Stack;var E:Element);
var
  top:pStackElem;
begin
  if S.Top<>nil then begin
    Move(S.Top^.Elem^,E,SizeOf(Element));  {было Move(S.Top^.Elem,E,SizeOf(Element));} 
    top:=S.Top^.Next;
    FreeMem(S.Top^.Elem,SizeOf(Element));{Вот здесь и возникает ОШИБКА!!!}
    dispose(S.Top);
    S.Top:=top;
    S.Size:=S.Size-Sizeof(Element)-SizeOf(pStackElem)*2-SizeOf(Pointer);
  end
end;
int64
Цитата(lapp @ 30.11.2006 14:56) *

Ты в операторе Move используешь указатель вместо самой величины. Этим самым ты портишь пойнтер.

ужас! какая глупая ошибка моя ... wacko.gif невнимательность (((
не таким образом я "разжевал" параметры процедуры Move )))
большое спасибо вам, lapp!
Lapp
Цитата(int64 @ 30.11.2006 16:27) *

ужас! какая глупая ошибка моя ... wacko.gif невнимательность (((

smile.gif бывает..
Хочешь совет? Если совсем ничего не получается долгое время, то начинай убирать из программы все "несущественное". Либо на некотором этапе ошибка пропадет (как сейчас), либо ты упростишь себе задачу, освободившись от шелухи.
Успехов!
volvo
А ошибка по-прежнему возникает... smile.gif

Переезжаем в Задачи...
int64
Цитата(volvo @ 30.11.2006 15:41) *

А ошибка по-прежнему возникает... smile.gif

Переезжаем в Задачи...

угу возникает - уже пофиксил wink.gif
а именно это исправил:
Код
procedure Pop(S:Stack;var E:Element);


на

Код
procedure Pop(var S:Stack;var E:Element);


TO lapp: да действительно не впервые.... хотя некоторые участки кода я убирал (комментировал) все равно не решало проблему... Все зависит от того насколько грубо мы ошиблись )
int64
еще один вопрос касаемый реализации стека...
Размер одного элемента стека.
Я таким образом его задал -
Код
sizeOne=Sizeof(Element)+SizeOf(pStackElem)*2+SizeOf(Pointer);


исходя из определенных типов данных
Код
StackElem = record   {Элемент стека}
              Elem:Pointer;       {указатель на данные}
              Next:pStackElem;
              end;
    Stack = record
          Top: pStackElem;
          Size: Integer;
          end;
    Element = record
            .....
            end;


я правильно рассудил?
Bokul
А почему нельзя просто
sizeOne=Sizeof(StackElem)

?
volvo
Цитата
А почему нельзя просто
Потому что это будет "неправильный мед" (С) Винни-Пух... Стек содержит указатель, который в свою очередь содержит адрес выделенной памяти, а насколько я понимаю автора, ему нужен именно размер области памяти, занимаемый самой структурой + той областью, где хранятся данные; то есть, насколько уменьшилось количество доступной памяти в куче при размещении в стеке очередного элемента...
int64
volvo верно рассудил good.gif

но ведь мне не очень то понятно что именно является "размером стека" - не путать с количеством элементов в стеке... Размер которые занимают данные? или размер всего структуры организации стека?
ну я выбрал последнее... правда на самом деле в из кучи при создании очередного элемента (путем new и GetMem) берется больше байтов чем в sizeOne..
Bokul
Цитата
правда на самом деле в из кучи при создании очередного элемента (путем new и GetMem) берется больше байтов чем в sizeOne.

Это ты о чем?
volvo
Цитата
Это ты о чем?
О том, что GetMem/New выделяют память блоками с размером кратным 8... yes2.gif
Bokul
Цитата
правда на самом деле в из кучи при создании очередного элемента (путем new и GetMem) берется больше байтов чем в sizeOne.

Это мы знали. smile.gif
Цитата
берется больше байтов чем в sizeOne..

Ну тогда, если это и имелось ввиду, то правильней будет - больше или ровно...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.