powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как сохранить в файл запись (record) с динамическими массивами?
20 сообщений из 45, страница 2 из 2
Как сохранить в файл запись (record) с динамическими массивами?
    #39744999
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

проца move работает с байтами, length(s) возвращает не количество байтов
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745003
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kealon(Ruslan),

у ansistring же длина равна кол-ву байт.

Если перед копированием запомнить указатели на rec.a и rec.a.s, то как их потом вернуть? Т.е., можно присвоить pointer'у адрес rec.a, а обратно - нет.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745004
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registeredу ansistring же длина равна кол-ву байт.У UTF8String кстати тоже.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745007
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

не забывай, что record выравнивается, соответственно между полями записи в памяти может быть разрыв.
у packet record все поля идут строго друг за другом
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745009
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вообще сама задача изначально странная. Я понимаю, что в качестве студенческой задачи пойдет. Но в реальном проекте использовать file of ?
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745016
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Хотя, вложенная структура, вроде, хранится не по указателю, а целиком в теле первой. Значит, второе "move" лишнее, и нужно разобраться только со строкой.
Оказалось, там строка string, а в неё копирую ansistring - не работает (это потому что уже кучу раз исправлял, и испортилось, а так там тоже копировалось по байтам).
В общем, перед "move" присвоить
Код: pascal
1.
p:=@rec.a.s;


потом
Код: pascal
1.
move(str1[1],rec,length(str1));


а потом
Код: pascal
1.
pointer(rec.a.s):=p;


и только потом -
Код: pascal
1.
rec.a.s:=str3;



А если "pointer(rec.a.s):=p;" убрать, тогда - error!
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745019
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

мой тебе совет - не делай так .
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745020
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну а как? Передать структуру, а потом её восстановить? Не по одному полю же?
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745026
Фэйтл Эра
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered,

автор
Код: pascal
1.
move(str1[1],rec,length(str1));


А если строка будет пустая - мув не сглючит?
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745035
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registered
Код: pascal
1.
move(str1[1],rec,length(str1));



Ну вот что это за адский пц?..
1) где выделение памяти под копию строки?
2) вы же в курсе, что строка - это указатель?.. т.е. вы копируете данные строки str1 в запись rec, которая у вас имеет размер 12 байт + выравнивание и этим самым портите значения других полей и память за этой записью;
3) копировать строки через move() - это такое себе. Если вам обязательно нужно получить отдельную копию строки в памяти, то делайте так:
Код: pascal
1.
2.
rec.a.s := str1;
UniqueString(rec.a.s); // тут, при необходимости, delphi сама создаст копию строки
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745036
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registeredА если "pointer(rec.a.s):=p;" убрать, тогда - error!

1. p:=@rec.a.s; - сохранили адрес строки s
2. move(str1[1],rec,length(str1)); - затёрли содержимое rec мусором из str1 (в т.ч. и адрес строки s)
3. pointer(rec.a.s):=p; - восстановили адрес строки s (чему равен pointer(rec.a.s) перед этой инструкцией?..)
4. rec.a.s:=str3; - присвоили строке s значение str3, при этом компилятор изменяет значение счётчика ссылок по адресу pointer(s) - 8 (afair).

Теперь догадаетесь почему без 3го шага у вас вылезает ошибка?..
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745175
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvpregistered
Код: pascal
1.
move(str1[1],rec,length(str1));



Ну вот что это за адский пц?..
1) где выделение памяти под копию строки?Так в этой же инструкции строка копируется в запись, для которой не нужно выделять память.
Если выделять память под rec.a.s перед копированием, чтобы получить правильный указатель на строку, то разницы нет (в этом случае).

alekcvp2) вы же в курсе, что строка - это указатель?.. т.е. вы копируете данные строки str1 в запись rec, которая у вас имеет размер 12 байт + выравнивание и этим самым портите значения других полей и память за этой записью;Ну если я сначала сохраняю такую же запись в строку, а потом восстанавливаю, значит такое же кол-во байт должно быть.

alekcvp3) копировать строки через move() - это такое себе. Если вам обязательно нужно получить отдельную копию строки в памяти, то делайте так:
Код: pascal
1.
2.
rec.a.s := str1;
UniqueString(rec.a.s); // тут, при необходимости, delphi сама создаст копию строки

Почему? Если память под 2-ю строку уже выделена нужной длины, то, вроде, как была, так и останется уникальная копия (хоть copy, хоть move), да и обычное присваивание тоже должно сделать уникальную копию.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745294
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registeredalekcvpпропущено...

Ну вот что это за адский пц?..
1) где выделение памяти под копию строки?Так в этой же инструкции строка копируется в запись, для которой не нужно выделять память.
Если выделять память под rec.a.s перед копированием, чтобы получить правильный указатель на строку, то разницы нет (в этом случае).

alekcvp2) вы же в курсе, что строка - это указатель?.. т.е. вы копируете данные строки str1 в запись rec, которая у вас имеет размер 12 байт + выравнивание и этим самым портите значения других полей и память за этой записью;Ну если я сначала сохраняю такую же запись в строку, а потом восстанавливаю, значит такое же кол-во байт должно быть.

Я попытаюсь ещё раз наглядно объяснить. Если всё равно не понимаете, то лучше сначала почитать какие-нибудь книжки по тому как устроена память ПК, что такое строки и указатели и чем они отличаются:
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745349
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpЯ попытаюсь ещё раз наглядно объяснить.
у Саши-GunSmoker'а в блоге весьма наглядная статья-перевод есть
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745375
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В str1 - не мусор, а такое же бинарное представление записи rec, сделанное ранее.
А строка по ссылке запоминается отдельно (в str3), и восстанавливается отдельно, после сохранения адреса rec.a.s, копирования str1 в rec, восстановления адреса, и потом уже присваивание значения строке из str3.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745408
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registeredВ str1 - не мусор, а такое же бинарное представление записи rec, сделанное ранее.
А строка по ссылке запоминается отдельно (в str3), и восстанавливается отдельно, после сохранения адреса rec.a.s, копирования str1 в rec, восстановления адреса, и потом уже присваивание значения строке из str3.
Ты понимаешь, что адрес в rec.a.s действителен только на момент его запоминания? На момент восстановления эта строка может находиться уже в совершенно другом месте и восстановленный адрес будет показывать на участок памяти, в котором хранится хрен-знает-что? И если строка по ссылке запоминается в str3, то этот адрес потом вообще не нужен. Достаточно запомнить (str3 = rec.a.s) и сохранить str3, а потом восстановить (rec.a.s := str3) и всё. Через move() можно сохранять только неуправляемые просты типы, вроде integer, cardinal, boolean, статических массивов и записей, состоящих только из таких же простых типов.
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745420
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registeredНу а как? Передать структуру, а потом её восстановить? Не по одному полю же?Ты не поверишь! Именно так и делают сериализаторы. Примеры можешь посмотреть в том-же Classes.pas
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745487
registered
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alekcvpИ если строка по ссылке запоминается в str3, то этот адрес потом вообще не нужен. Достаточно запомнить (str3 = rec.a.s) и сохранить str3, а потом восстановить (rec.a.s := str3) и всё.Так не работает. Access violation.

Код: pascal
1.
2.
move(str1[1],rec,length(str1)); // копируем структуру, затираем адрес rec.a.s
rec.a.s := str3; // AV - вероятно, он хочет освободить строку по старому адресу



Код: pascal
1.
2.
3.
4.
rec.a.s := str3; // сразу скопируем строку, выделяя новую память
p:=pointer(rec.a.s); // не @rec.a.s, а pointer(rec.a.s)
move(str1[1],rec,length(str1)); // копируем структуру
pointer(rec.a.s):=p; // восстанавливаем адрес строки
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745509
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
registeredТак не работает. Access violation.
Код: pascal
1.
2.
move(str1[1],rec,length(str1)); // копируем структуру, затираем адрес rec.a.s
rec.a.s := str3; // AV - вероятно, он хочет освободить строку по старому адресу


Именно то, о чём я говорил: вы командой Move() затираете действительный адрес с мусором (т.е. устаревшим адресом s, который сейчас содержит неизвестно что), поэтому присвоение в следующей строке вызывает ошибку. Поэтому поля записи с динамическими типами следует вообще исключить из сохранения через move() и сохранять их отдельно. И да, проще всего это сделать через сохранение каждого поля отдельно.

Ну или так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
type ta=packed record
s:string;
i:integer;
end;

type trec=packed record;
a:ta;
i:integer;
end;

.........
var
  str1: TBytes;
  str3: string;

{ Сохранение }
StaicSize = SizeOf(rec.a.i) + SizeOf(rec.i);
SetLength(str1, StaticSize);
Move(rec.a.i, str1[1], StaticSize);
str3 := rec.a.s;

{ Восстановление }
Move(str1[1], rec.a.i, StaticSize);
rec.a.s := str3;
...
Рейтинг: 0 / 0
Как сохранить в файл запись (record) с динамическими массивами?
    #39745529
Sapersky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Насмотревшись на ваши мучения, решил-таки выложить свой модуль для автоматического сохранения подобных структур.
Я не буду его хвалить и пиарить, это гнусное хакерство (поскольку писалось ещё до "новой" RTTI) и я сам им уже не пользуюсь - в основном потому, что не использую структуры с многоуровневой вложенностью массив-запись-массив. Всё-таки они неудобны по многим причинам.
Хотя с современными навороченными рекордами может и есть какой-то смысл.
...
Рейтинг: 0 / 0
20 сообщений из 45, страница 2 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как сохранить в файл запись (record) с динамическими массивами?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]