Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.02.27;
Скачать: CL | DM;

Вниз

Чтение и запись динамического массива   Найти похожие ветки 

 
Sicilla ©   (2005-01-14 20:49) [0]

Добрый день! Есть такой кусок кода:
type
   E = record
     full: byte;
     Speed: array[1..6] of int64;
     IP: array[1..6] of string[35];
     name: array[1..6] of string[255];
     In_byte: array[1..6] of real;
     Out_byte: array[1..6] of real;
end;
var E_info: ^E;
begin
    GetMem(E_info, sizeof(E));
    Get_IfTable();
// здесь работа с данными
    {$IFDEF VER80}
    FreeMem(E_info, sizeof(E));
    {$ELSE}
    FreeMem(E_info);
    {$ENDIF}
end;

Вопрос такой: как мне полученный массив E_info сохранить в файле, а затем при необходимости его прочитать? Заранее спасибо.


 
Kerk ©   (2005-01-14 20:51) [1]

BlockWrite


 
begin...end ©   (2005-01-14 20:54) [2]

> Sicilla ©   (14.01.05 20:49)

> как мне полученный массив E_info сохранить в файле, а затем
> при необходимости его прочитать?

А разве E_info - это динамический массив?

E_info здесь - это УКАЗАТЕЛЬ. И сохранять значение указателя в файл, а тем более - читать его оттуда, совершенно незачем.


 
begin...end ©   (2005-01-14 21:16) [3]

> Sicilla ©   (14.01.05 20:49)

А если Вы хотите сохранить данные, на которые указывает переменная E_info, то это можно сделать так:

type
 E = record
   ...
 end;

var
 E_info: ^E;
 MyFile: file of E;

begin
 ...
 // Тут данные по адресу E_info уже готовы к сохранению
 AssignFile(MyFile, "...");
 Rewrite(MyFile);
 Write(MyFile, E_info^);
 CloseFile(MyFile);
 ...
end.

А можно и с помощью НЕтипизированных файлов - см. [1].

P.S. Кстати, какой смысл с типизированным указателем E_info работать с помощью GetMem/FreeMem вместо New/Dispose? ИМХО, New/Dispose проще.


 
Sicilla ©   (2005-01-15 07:47) [4]

begin...end! Спасибо. Расскажи пооподробнее, если не трудно Кстати, какой смысл с типизированным указателем E_info работать с помощью GetMem/FreeMem вместо New/Dispose? ИМХО, New/Dispose проще.


 
Kerk ©   (2005-01-15 07:56) [5]

Sicilla ©   (15.01.05 7:47) [4]
разницы никакой. просто New/Dispose проще.


 
VMcL ©   (2005-01-15 09:47) [6]

>>Kerk ©  (15.01.05 07:56) [5]

В общем случае разница есть. New/Dispose, в отличие GetMem/FreeMem, производят инициализацию/финализацию объектов с управляемым временем жизни (длинных строк, экземпляров интерфейсов etc.)


 
Sicilla ©   (2005-01-15 11:56) [7]

Все понятно, спасибо. у меня сейчас такая проблема:

function button1click; // к примеру
    mem_ethernet(true); //здесь выделяется память
    mem_e_info(true);
    Get_IfTable();
    for i := 1 to E_info^.full do
        begin
             if pos("S TCP",E_info^.name[i]) = 0 then
                begin
                     TGroupbox(Findcomponent("GBox"+inttostr(j))).Caption := E_info^.name[j];
                     for k := 1 to 2 do
                         if ethernet^.Name[k] = E_info^.name[j] then find_card := 1;
                     inc(j);
                end;
        end;
    mem_ethernet(false);
    mem_e_info(false);

Здесь все определяется. а вот:
function button2click // к примеру
            mem_ethernet(true);
            mem_e_info(true);
            Get_AdaptersInfo(); Get_IfTable();
            j := 1;
            for i := 1 to e_info^.full do
                if pos("S TCP",E_info^.name[i]) = 0 then
                   begin
                        Ethernet^.Name[j] := E_info^.name[i];
                        Ethernet^.rec[j] := 0; // количество записей
                        Ethernet^.control[j] := "3"; // настройка сохранения
                        inc(j);
                   end;
            mem_ethernet(false);
            mem_e_info(false);

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


 
Kerk ©   (2005-01-15 11:58) [8]

Sicilla ©   (15.01.05 11:56) [7]
объяви его глобально


 
Sicilla ©   (2005-01-15 12:04) [9]

В том то и дело, что мне его не охота объявлять глобально. Программа тогда занимает в два раза больше памяти - 12 метров. Вот в чем дело.


 
Kerk ©   (2005-01-15 12:07) [10]

Sicilla ©   (15.01.05 12:04) [9]
больше никак


 
Sicilla ©   (2005-01-15 12:34) [11]

Хорошо. Тогда как сделать динамический массив, так чтобы в начале там была 1 запись, потом я мог добавить еще несколько записей в процессе работы. Все эти записи сохраняются в файле. Потом, при загрузке программы загружались уже все записи этого массива. Массив на 1000 записей, тип record. Подскажи, если не трудно.


 
begin...end ©   (2005-01-15 18:08) [12]

> [11] Sicilla ©   (15.01.05 12:34)

> Тогда как сделать динамический массив, так чтобы в начале
> там была 1 запись, потом я мог добавить еще несколько записей
> в процессе работы.

type
 TMyRec = record
   ...
 end;

var
 MyRecArray: array of TMyRec;

begin
 // Делаем массив длиной в 1 элемент
 SetLength(MyRecArray, 1);
 MyRecArray[0] := ...;
 ...
 // Теперь понадобилось увеличить длину массива на единицу, делаем это:
 SetLength(MyRecArray, Length(MyRecArray) + 1);
 MyRecArray[High(MyRecArray)] := ...;
 ...
 // Массив больше не нужен, освобождаем память, занятую им:
 MyRecArray := NIL
end.

Но я по-прежнему не вижу у Вас в коде никаких динамических массивов.

> [6] VMcL ©   (15.01.05 09:47)

А вот меня давно интересует такой вопрос. Если при "инициализации" нетипизированного указателя с помощью GetMem задать размер выделяемой памяти, а при освобождении (FreeMem) этот размер не указать, то по показаниям AllocMemCount выходит, что освобождается вся ранее выделенная память. Я встречал примеры кода, где размер при освобождении и указывается, и не указывается. Так вот - вопрос: нужно ли это делать обязательно? И если это необязательно, то откуда вообще при выполнении FreeMem берётся информация о том, сколько памяти нужно освободить?


 
Kerk ©   (2005-01-15 18:34) [13]

begin...end ©   (15.01.05 18:08) [12]
И если это необязательно, то откуда вообще при выполнении FreeMem берётся информация о том, сколько памяти нужно освободить?

там перед выделенным блоком памяти идет служебная информация


 
Kerk ©   (2005-01-15 18:35) [14]

имхо :)


 
VMcL ©   (2005-01-15 23:27) [15]

>>begin...end ©  (15.01.05 18:08) [12]

>о показаниям AllocMemCount выходит, что освобождается вся ранее выделенная память.

По другому и быть не может. Второй параметр оставлен для совместимости с BP7, AFAIK.

procedure FreeMem(var P: Pointer[; Size: Integer]);

Size specifies the size in bytes of the dynamic variable to dispose of; if specified, it must be exactly the number of bytes previously allocated to that variable by GetMem.


>Так вот - вопрос: нужно ли это делать обязательно?

Нет. Я бы даже сказал, что совсем не нужно, потому что часто это просто неудобно.

>>Kerk ©  (15.01.05 18:34) [13]

Из таблицы менеджера памяти размер берётся, если не ошибаюсь.


 
Kerk ©   (2005-01-16 00:03) [16]

VMcL ©   (15.01.05 23:27) [15]
Из таблицы менеджера памяти размер берётся, если не ошибаюсь.

весьма вероятно.. возможно я с VC путаю..


 
begin...end ©   (2005-01-16 10:04) [17]

> [15] VMcL ©   (15.01.05 23:27)

Спасибо :-)



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

Текущий архив: 2005.02.27;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.024 c
1-1108050696
miwa
2005-02-10 18:51
2005.02.27
Есть ли штатная возможность расширения выпадающей части ТListBox?


1-1108447358
ТехникПТО
2005-02-15 09:02
2005.02.27
Продолжите плиз...


4-1105463184
aglar
2005-01-11 20:06
2005.02.27
Копирование директории


3-1106688163
MakedoneZ
2005-01-26 00:22
2005.02.27
Про компонент DBGrid и тип данных Boolean.


14-1107446927
Piter
2005-02-03 19:08
2005.02.27
Плагин к Миранде