Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.05.2020, 05:26   #1
bvn123
Новичок
Джуниор
 
Регистрация: 03.05.2020
Сообщений: 2
По умолчанию TFileStream и многомерный динамический массив

Сохранение многомерного динамического массива посредством TFileStream выполняется неверно.
Для проверки сохраняю и статический массив с таким же содержимым.

Код:
const   maxC=100; maxD=80;
type
  TDatRec = record
        rDateTime:TDateTime;
        rVol:DWord;         end;

  TArStat =  array[0..maxC-1] of array[0..maxD-1] of TDatRec;
  TArDyn  =  array of array of TDatRec;

var     arDyn:TArDyn;
        arSt:TArStat;

procedure TForm1.btDynArSaveClick(Sender: TObject);
var     i,j:integer;
         p:^TByteArray;
begin
  memo.Clear;
  fStream:=TFileStream.Create('c:\1.txt',fmCreate);
  setLength(arDyn,maxC,maxD);
  for i:=0 to maxC-1 do
    for j:=0 to maxD-1 do begin
      arDyn[i,j].rDateTime:=Now+j;     //формирование динамического массива
      arDyn[i,j].rVol:=i*1000+j;
      arSt[i,j].rDateTime :=Now+j;     //формирование статического массива
      arSt[i,j].rVol :=i*1000+j;
    end;

//  fStream.WriteBuffer(arSt,maxC*maxD*sizeOf(TDatRec));             //вариант сохранения статического массива
  fStream.WriteBuffer(arDyn[0,0],maxC*maxD*sizeOf(TDatRec));         //вариант1 сохранения динамического массива
//  fStream.WriteBuffer(arDyn,maxC*maxD*sizeOf(TDatRec));            //вариант2 сохранения динамического массива
// p:=@arDyn[0,0]; fStream.WriteBuffer(p^,maxC*maxD*sizeOf(TDatRec)); //вариант 3

  fStream.Free;
//  setLength(arDyn,0,0);    //убрано, чтобы убедиться в целостности динамического массива после сохранения (следующая процедура)
end;

procedure TForm1.rdRecClick(Sender: TObject);
var i,j:        integer;
begin
i:=seI.Value; j:=seJ.Value;   //ввод индексов массива
memo.Lines.Add(format('%0.4f  %d',[ arSt[i,j].rDateTime, arSt[i,j].rVol]));  //проверка целостности массивов
memo.Lines.Add(format('%0.4f  %d',[arDyn[i,j].rDateTime,arDyn[i,j].rVol]));
end;

end.
"\\Вариант сохранения статического массива" выполняется нормально,
если вместо него использовать приведенные
варианты сохранения динамического массива, результат оказывается некорректным:
Вариант 1 сохраняет хотя бы часть верных значений.

После сохранений проверяю целостность динамического массива (procedure TForm1.RdRecDClick), сравнивая его отдельные элементы с такими же элементами статического - они одинаковы.

Подскажите, в чем ошибка?
bvn123 вне форума Ответить с цитированием
Старый 03.05.2020, 06:20   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,285
По умолчанию

Многомерный динамический массив не хранится одним непрерывным куском в памяти, в отличие от статического. Попробуйте записать его в файл построчно.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA на форуме Ответить с цитированием
Старый 03.05.2020, 08:32   #3
bvn123
Новичок
Джуниор
 
Регистрация: 03.05.2020
Сообщений: 2
По умолчанию

BDA, большое спасибо за ответ,
он соответствует тому, что я наблюдал: сначала из отладчика динамический массив сохранялся полностью, затем запустил exe - в массиве появился непонятный кусок; при выделении небольшого фрагмента в отдельную программу (чтобы разобраться), в сохраненных данных вдруг оказывались и осмысленные строки, содержащие, например, путь к сохраняемому файлу (он вычисляется в этой программе), к тому же первая строка часто сохранялась.

Вариант со строками меня вполне устраивает, да и массив всего в сотни КБайт, но интересно,
нельзя ли динамический массив привязать к выделению памяти одним куском, что-то вроде GetMem()?
Или getmem() также не выделяет единого фрагмента памяти?
Я попробовал так: getmem(arDyn,maxC*maxD*sizeOf(TDatR ec));
не работает, добавил setLengtn(arDyn,maxC,maxD); - тоже не работает.

Последний раз редактировалось bvn123; 03.05.2020 в 09:06.
bvn123 вне форума Ответить с цитированием
Старый 04.05.2020, 04:18   #4
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,859
По умолчанию

Цитата:
Сообщение от bvn123 Посмотреть сообщение
нельзя ли динамический массив привязать к выделению памяти одним куском
Нельзя не переписывая генофонд. И самое главное. Это ваше пожелание никому кроме вас не нужно. А если разобраться, то и вам оно наверняка не нужно.
northener на форуме Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Многомерный массив СтудПом Общие вопросы C/C++ 6 24.11.2017 17:21
Многомерный массив Должно быть имя? Общие вопросы Delphi 9 03.05.2015 20:34
Многомерный динамический массив С++Builder Karina89 Помощь студентам 1 16.11.2011 18:38
Динамический многомерный массив Lazy maximka Помощь студентам 8 25.04.2011 17:46
Как создать многомерный динамический массив в Delphi? Velross Помощь студентам 3 06.01.2010 20:50