Модераторы: volvo877, Snowy, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Pascal, указатели и динамическая память 
:(
    Опции темы
Mager2005
Дата 9.5.2005, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 7.4.2005

Репутация: нет
Всего: нет



Народ! Help, как говориться. Растолкуйте бестолковым начинающим, принцип работы динамической памяти и указателей. У меня тут задачка по базе данных. не могу разобраться что к чему.
Отрывок:

Код
type lib=record
     fio:string[50];
     marka:string[20];
     nomer :string[30];
     color :string;
         end;
type pitem=^item;
 item=record
 data:lib;
 next:pitem;
 end;
Var head,p,p1:pitem;
    w,n,k,q:integer;
    l:lib;
    h,c:char;
    f:file of lib;
    s:string[8];
  v, d:string;
   a:MasMenu;
   sim:Byte;
   j,i:Longint;
===========================
i:=0;
    while not(eof(f)) do begin
    inc(i);
    read(f,l);
    if q<>0 then begin for i:=1 to q do begin { and (i<=n) and (head<>nil) then }
        if i=1 then begin
        p:=head^.next;
        dispose(head);
        head:=p;    end
                    else begin
                         p:=head;
                         for k:=2 to i-1 do p:=p^.next;
                         p1:=p^.next;
                         p^.next:=p1^.next;
                         dispose(p1);
                         end;
     n:=n-1;            end;end;

    add(l,i);


PS пл по-подробнее растолкуйте smile



Это сообщение отредактировал(а) Fedor - 9.5.2005, 22:32
PM MAIL ICQ   Вверх
SPrograMMer
Дата 9.5.2005, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Спамер :)
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 5.11.2004
Где: Краснодар

Репутация: нет
Всего: 6



Тут чутка про очереди - структуры данных, которые тебе надо реализовать.
А вообще я понял у тебя есть типизирвоанный файл, и тебе его надо в динмаческую память отправить?
Добавлено @ 23:21
Цитата(Mager2005 @ 9.5.2005, 22:30)
Код

p:=head^.next;
        dispose(head);
        head:=p;

.....этот кусок деляет вроде первый элемент... ну все верно....




Цитата(Mager2005 @ 9.5.2005, 22:30)
Код

p:=head;
                         for k:=2 to i-1 do p:=p^.next;
                         p1:=p^.next;
                         p^.next:=p1^.next;
                         dispose(p1);

...а этот вроде деляет предпоследний (или последний) элемет....
smile smile smile не соображу тогда чего тебе надо.......


--------------------
животное = зверь
законченный гентушник
PM MAIL ICQ Jabber   Вверх
Mager2005
Дата 10.5.2005, 00:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 7.4.2005

Репутация: нет
Всего: нет



Все очень просто мне нужно объяснить что тут к чему вот и все. А какой кусок какой элемент делает - эт и так ясно. Ты б лучше пояснил, как он это делает smile
PM MAIL ICQ   Вверх
Mager2005
Дата 10.5.2005, 03:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 7.4.2005

Репутация: нет
Всего: нет



Цитата
Тут чутка про очереди - структуры данных, которые тебе надо реализовать.

Спасибо, надо было сразу в FAQ посмотреть smile
PM MAIL ICQ   Вверх
SPrograMMer
Дата 10.5.2005, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Спамер :)
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 5.11.2004
Где: Краснодар

Репутация: нет
Всего: 6



Цитата(Mager2005 @ 10.5.2005, 00:17)
как он это делает

Цитата(Mager2005 @ 10.5.2005, 03:23)
Спасибо, надо было сразу в FAQ посмотреть

значит разобрался?....


--------------------
животное = зверь
законченный гентушник
PM MAIL ICQ Jabber   Вверх
Mager2005
Дата 10.5.2005, 23:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 7.4.2005

Репутация: нет
Всего: нет



И да и нет. Вроде понятен принцип. Вот только такая фишка получается. Программа при запуске выдает на строчке dispose (head) - Invalid pointer operation, а на строчке new(p) - Heap overflow error. Что ей не нравится - не могу понять smile
PM MAIL ICQ   Вверх
Fedor
Дата 11.5.2005, 06:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Днепрянин
****


Профиль
Группа: Участник
Сообщений: 2090
Регистрация: 8.2.2003
Где: Великий

Репутация: нет
Всего: 32



Mager2005 выложи полностью код


--------------------
Мы - Днепряне. Мы всех сильней.
PM ICQ   Вверх
SPrograMMer
Дата 11.5.2005, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Спамер :)
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 5.11.2004
Где: Краснодар

Репутация: нет
Всего: 6



Цитата(Mager2005 @ 10.5.2005, 23:31)
dispose (head) - Invalid pointer operation

Это значит, что у тебя head содержит что-то, что не nil - "пусой" указатель, но однако это место памяти НЕ БЫЛО ранее выделено подпрограммой new => там находится или "мусор" или статические данные, в общем потому что эта память ранее не выделалась.
Что бы этого не происходило, ВЕЗДЕ, где есть указатели, после освободения памяти им нужно всегда присваивать nil ЯВНО. Дабы не наткнуться на него же во второй раз smile



Цитата(Mager2005 @ 10.5.2005, 23:31)
на строчке new(p) - Heap overflow error

так назваемое переполнениеи "кучи", т. е области динамической памяти.
Если там не хватает места для выделения, то вызывается подпрограма, которая находится по адресу, которая хранится в переменной HeapError, хоть ты эту переменную не объявлял, она у тебя есть smile . "Решается" эта проблема обычно следующим образом: пишется своя подпрограммка по обработки состояния "нет_памяти"- HeapError, и заменяется стандарт, ну примерно так:
Код

Var
  SaveHeapError:Pointer;//для сохранения адреса стандартной подпрограммы
{$F+}    // надо!
Function NewHeapError(Size:Word):Integer;
Begin
  NewHeapError:=1   // как тока не будет хватать памяти ошибок не возбуждать, но вернуть
                                 // nil при попытке получить часть памяти
End;
{$F-}
Procedure GetAnyDynamicMemory;
  Var
      X:PRecord;
Begin
    HeapError:=@NewHeapError;  // заменяем стандарт
   X:=New(PRecord);  // попытаться выделить память
   If X=Nil Then  // если не получилось
      // чего-нить делать, например сообщить пользователю, что нет памяти
   Else Begin
      // продолжаем работать с переменной Х
      X^........
   End;
   H eapError:=SaveHeapError // возвращаем стандарт
End;
....
Begin
   SaveHeapError:=HeapError;  // Сохраняем стандартную функцию
   // работаем с памятью:
  GetAnyDynamicMemory;
  ......
End.


Нехватка памяти, как ты наверное понимаешь происходит из-за того. что твоя запись СИЛЬНО большая, и может быть превашает 64 К , а структуры данных сразу непосредственно, превышающие 64 К разместить в памяти нельзя => частями надо....

Это сообщение отредактировал(а) SPrograMMer - 11.5.2005, 11:48


--------------------
животное = зверь
законченный гентушник
PM MAIL ICQ Jabber   Вверх
Mager2005
Дата 11.5.2005, 20:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 7.4.2005

Репутация: нет
Всего: нет



SPrograMMer: и как можно решить проблему с head и new. И вообще как разместить запись в памяти частями???

Fedor: значит код моей базы данных такой:

Код

uses crt;
type  
     base=record
      name:string;
      processor:string;
      interf:string;
      system_bus_clockrate:string;
      max_processor:string;
      memory_type:string;
      ATA:string;
      USB:string;
      AGP:string;
      end;
type  point=^part;
      part=record
      data:base;
      next:point;
      end;
const 
      n=6;x=30;y=10;number=9;
      normal=$17;
      selected=$60;
var
     head,p,p1:point;
     menu:array [1..number] of string;
     a:array [1..n] of string;
     i,item,q,l:byte;
     ch:char;
     f:file of base;
     path:string;
     x1,y1:word;
================
procedure file_new(var path:string); (определяем имя загружаемого файла)
var j:byte;nam:string;
begin
clrscr;
path:='';
gotoxy(x,y);
write('Input the name of a new file: ');
read(nam);
readln;
path:=nam;
end;

procedure printing(l:byte); (печатаем данные из файла)
var i,j:byte; x2,y2:word;
begin
p1:=head; i:=0;
repeat
     x2:=34+i*l+1; y2:=2;
     gotoxy(x2,y2); for j:=1 to l do write(' ');
     gotoxy(x2,y2); write (p1^.data.name);
     gotoxy(x2,y2+2); for j:=1 to l do write(' ');
     gotoxy(x2,y2+2); write (p1^.data.processor);
     gotoxy(x2,y2+4); for j:=1 to l do write(' ');
     gotoxy(x2,y2+4); write (p1^.data.interf);
     gotoxy(x2,y2+6); for j:=1 to l do write(' ');
     gotoxy(x2,y2+6); write (p1^.data.system_bus_clockrate);
     gotoxy(x2,y2+8); for j:=1 to l do write(' ');
     gotoxy(x2,y2+8); write (p1^.data.max_processor);
     gotoxy(x2,y2+10); for j:=1 to l do write(' ');
     gotoxy(x2,y2+10); write (p1^.data.memory_type);
     gotoxy(x2,y2+12); for j:=1 to l do write(' ');
     gotoxy(x2,y2+12); write (p1^.data.ATA);
     gotoxy(x2,y2+14); for j:=1 to l do write(' ');
     gotoxy(x2,y2+14); write (p1^.data.USB);
     gotoxy(x2,y2+14); for j:=1 to l do write(' ');
     gotoxy(x2,y2+14); write (p1^.data.AGP);
     p1:=p1^.next;
     inc(i);
until p1=nil;
end;

procedure loading(i:byte; chipset:base); (загружаем данные в оперативную память)
var j:byte;
begin
while i<=q do
     if i=1 then
     begin
     new(p);
     p^.data:=chipset;
     if i=1 then
     begin
     p^.next:=head;head:=p;
     end
     else begin
          p1:=head;
          for j:=2 to i-1 do p1:=p1^.next;
          p^.next:=p1^.next;
          p1^.next:=p;
      end;
      {new(p);
      p^.data:=chipset; writeln(p^.data.name); readkey;
      p^.next:=head;
      head:=p;
      {writeln(head^.data.name);
     end
     else
     begin
      p1:=head;
      for j:=1 to i-1 do p1:=p1^.next;
      p1^.next:=p;
      p:=p1;}
     end;
     readkey;
end;

procedure reading (x,y:word);(читаем данные из файла)
var name:string; i,j,k:byte;
begin
file_new(path);
assign(f,path);
{$I-}
reset(f);
{$I+}
if IOResult<>0 then begin gotoxy(x,y+1); write('File is not found.'); end
   else
   begin
   i:=0;
   while not eof(f) do
   begin
       inc(i);
       read(f,chipset); 
       if q<>0 then begin for i:=1 to q do begin { and (i<=n) and (head<>nil) then }
       if i=1 then begin
       p:=head^.next;
       dispose(head);
       head:=p;    
       end
                    else begin
                         p:=head;
                         for k:=2 to i-1 do p:=p^.next;
                         p1:=p^.next;
                         p^.next:=p1^.next;
                         dispose(p1);
                         end;       end;end;


   loading(i,chipset);
   end;
   gotoxy(x,y+1);
   write('The loading has passed aptly.');
   end;
gotoxy(x,y+2);
write('Press <Enter>');
readkey;
end;
================================(запись данных в файл - первоначальное создание БД)
procedure inputchar(var mas:string);
var h:char;
begin
h:=readkey;
mas:='';
while (h<>#13) do
begin
mas:=mas+h;
write(h);
h:=readkey;
end;
end;

procedure kursor(item:byte);forward;

procedure create(x:byte);
var j,k:byte; mas:string; c:char;
begin
file_new(path);
assign (f,path);
rewrite (f);
q:=0;
repeat
inc(q);
table(number,31,x,true);
for i:=1 to number do
    begin
    gotoxy(x,y+i-1);
    write(menu[i]);
    end;
gotoxy (32,6);
write('Database creating');
for i:=1 to number do
    begin
    if i>1 then
           begin
          gotoxy(x+31,y+i-2);
          textbackground(blue);
          for j:=1 to 14 do write(' ');
          gotoxy(x+31,y+i-2);
          write (mas);
           end;
    gotoxy(x+31,y+i-1);
    textbackground(green);
    for j:=1 to 14 do write(' ');
    gotoxy(x+31,y+i-1);
    inputchar(mas);
    case i of
         1:chipset.name:=mas;
         2:chipset.processor:=mas;
         3:chipset.interf:=mas;
         4:chipset.system_bus_clockrate:=mas;
         5:chipset.max_processor:=mas;
         6:chipset.memory_type:=mas;
         7:chipset.ATA:=mas;
         8:chipset.USB:=mas;
         9:chipset.AGP:=mas;
              end;
    if i=number then begin
                gotoxy(x+31,y+i-1);
                textbackground(blue);
                for j:=1 to 14 do write(' ');
                gotoxy(x+31,y+i-1);
                write (mas);
             end;
     end;
gotoxy(30,20);
write('One more record (y/n)? ');
c:=readkey;
write(f,chipset);
until c=#110;
close(f);
end;


ну там еще несколько процедур: создание таблиц, управление курсором и т.д.



Это сообщение отредактировал(а) Fedor - 11.5.2005, 21:38
PM MAIL ICQ   Вверх
Fedor
Дата 11.5.2005, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Днепрянин
****


Профиль
Группа: Участник
Сообщений: 2090
Регистрация: 8.2.2003
Где: Великий

Репутация: нет
Всего: 32



Mager2005 Используйте пожалуйста теги CODE для обраления кода.


--------------------
Мы - Днепряне. Мы всех сильней.
PM ICQ   Вверх
Mager2005
Дата 14.5.2005, 22:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 7.4.2005

Репутация: нет
Всего: нет



Народ! Нашлось решение. Ура !!!! Все намного проще, чем казалось. И кто бы мог подумать.
Значит, здесь вместо двух процедур reading и loading надо записать следующее:
Код

procedure read_in_memory (x,y:word;);
var name:string; i,j:byte;
begin
file_new(path);
assign(f,path);
{$I-}
reset(f);
{$I+}
if IOResult<>0 then begin gotoxy(x,y+1); writeln('File is not found'); end
else
begin
head:=nil;
while not eof(f) do
      begin
      read(f,chipset);
      if head=nil then
               begin
               new(p);
               head:=p;
               end
          else
               begin
               new(p^.next);
               p:=p^.next;
               end;
      p^.data:=chipset;
      p^.next:=nil;
      end;
gotoxy(x,y+1);
write('The loading has passed successfully....');
end; 
gotoxy(x,y+2);
write('Press <Enter>');
readkey;
end;

Что значит, если долго мучиться, что-нить да получится smile
Правда, решение не мое, и все же .....
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi"
THandle
Rrader
volvo877

Запрещается!

1. Обсуждать и делится взломанными компонентами или программным обеспечением

2. Публиковать ссылки на варез

3. Оффтопить

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, THandle, Rrader, volvo877.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Object Pascal: кроссплатформенные технологии | Следующая тема »


 




[ Время генерации скрипта: 0.0782 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.