|
|
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
registered, проца move работает с байтами, length(s) возвращает не количество байтов ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2018, 19:49 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
kealon(Ruslan), у ansistring же длина равна кол-ву байт. Если перед копированием запомнить указатели на rec.a и rec.a.s, то как их потом вернуть? Т.е., можно присвоить pointer'у адрес rec.a, а обратно - нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2018, 20:08 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
registeredу ansistring же длина равна кол-ву байт.У UTF8String кстати тоже. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2018, 20:10 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
registered, не забывай, что record выравнивается, соответственно между полями записи в памяти может быть разрыв. у packet record все поля идут строго друг за другом ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2018, 20:15 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
А вообще сама задача изначально странная. Я понимаю, что в качестве студенческой задачи пойдет. Но в реальном проекте использовать file of ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2018, 20:17 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
Хотя, вложенная структура, вроде, хранится не по указателю, а целиком в теле первой. Значит, второе "move" лишнее, и нужно разобраться только со строкой. Оказалось, там строка string, а в неё копирую ansistring - не работает (это потому что уже кучу раз исправлял, и испортилось, а так там тоже копировалось по байтам). В общем, перед "move" присвоить Код: pascal 1. потом Код: pascal 1. а потом Код: pascal 1. и только потом - Код: pascal 1. А если "pointer(rec.a.s):=p;" убрать, тогда - error! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2018, 21:07 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
registered, мой тебе совет - не делай так . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2018, 21:33 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
Ну а как? Передать структуру, а потом её восстановить? Не по одному полю же? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2018, 21:39 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
registered, автор Код: pascal 1. А если строка будет пустая - мув не сглючит? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2018, 21:55 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
registered Код: pascal 1. Ну вот что это за адский пц?.. 1) где выделение памяти под копию строки? 2) вы же в курсе, что строка - это указатель?.. т.е. вы копируете данные строки str1 в запись rec, которая у вас имеет размер 12 байт + выравнивание и этим самым портите значения других полей и память за этой записью; 3) копировать строки через move() - это такое себе. Если вам обязательно нужно получить отдельную копию строки в памяти, то делайте так: Код: pascal 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2018, 22:50 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
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го шага у вас вылезает ошибка?.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.12.2018, 22:57 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
alekcvpregistered Код: pascal 1. Ну вот что это за адский пц?.. 1) где выделение памяти под копию строки?Так в этой же инструкции строка копируется в запись, для которой не нужно выделять память. Если выделять память под rec.a.s перед копированием, чтобы получить правильный указатель на строку, то разницы нет (в этом случае). alekcvp2) вы же в курсе, что строка - это указатель?.. т.е. вы копируете данные строки str1 в запись rec, которая у вас имеет размер 12 байт + выравнивание и этим самым портите значения других полей и память за этой записью;Ну если я сначала сохраняю такую же запись в строку, а потом восстанавливаю, значит такое же кол-во байт должно быть. alekcvp3) копировать строки через move() - это такое себе. Если вам обязательно нужно получить отдельную копию строки в памяти, то делайте так: Код: pascal 1. 2. Почему? Если память под 2-ю строку уже выделена нужной длины, то, вроде, как была, так и останется уникальная копия (хоть copy, хоть move), да и обычное присваивание тоже должно сделать уникальную копию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2018, 11:10 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
registeredalekcvpпропущено... Ну вот что это за адский пц?.. 1) где выделение памяти под копию строки?Так в этой же инструкции строка копируется в запись, для которой не нужно выделять память. Если выделять память под rec.a.s перед копированием, чтобы получить правильный указатель на строку, то разницы нет (в этом случае). alekcvp2) вы же в курсе, что строка - это указатель?.. т.е. вы копируете данные строки str1 в запись rec, которая у вас имеет размер 12 байт + выравнивание и этим самым портите значения других полей и память за этой записью;Ну если я сначала сохраняю такую же запись в строку, а потом восстанавливаю, значит такое же кол-во байт должно быть. Я попытаюсь ещё раз наглядно объяснить. Если всё равно не понимаете, то лучше сначала почитать какие-нибудь книжки по тому как устроена память ПК, что такое строки и указатели и чем они отличаются: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2018, 13:22 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
alekcvpЯ попытаюсь ещё раз наглядно объяснить. у Саши-GunSmoker'а в блоге весьма наглядная статья-перевод есть ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2018, 14:20 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
В str1 - не мусор, а такое же бинарное представление записи rec, сделанное ранее. А строка по ссылке запоминается отдельно (в str3), и восстанавливается отдельно, после сохранения адреса rec.a.s, копирования str1 в rec, восстановления адреса, и потом уже присваивание значения строке из str3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2018, 14:40 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
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, статических массивов и записей, состоящих только из таких же простых типов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2018, 15:24 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
registeredНу а как? Передать структуру, а потом её восстановить? Не по одному полю же?Ты не поверишь! Именно так и делают сериализаторы. Примеры можешь посмотреть в том-же Classes.pas ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2018, 15:33 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
alekcvpИ если строка по ссылке запоминается в str3, то этот адрес потом вообще не нужен. Достаточно запомнить (str3 = rec.a.s) и сохранить str3, а потом восстановить (rec.a.s := str3) и всё.Так не работает. Access violation. Код: pascal 1. 2. Код: pascal 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2018, 16:58 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
registeredТак не работает. Access violation. Код: pascal 1. 2. Именно то, о чём я говорил: вы командой 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2018, 17:36 |
|
||
|
Как сохранить в файл запись (record) с динамическими массивами?
|
|||
|---|---|---|---|
|
#18+
Насмотревшись на ваши мучения, решил-таки выложить свой модуль для автоматического сохранения подобных структур. Я не буду его хвалить и пиарить, это гнусное хакерство (поскольку писалось ещё до "новой" RTTI) и я сам им уже не пользуюсь - в основном потому, что не использую структуры с многоуровневой вложенностью массив-запись-массив. Всё-таки они неудобны по многим причинам. Хотя с современными навороченными рекордами может и есть какой-то смысл. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.12.2018, 17:55 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=39745420&tid=2040021]: |
0ms |
get settings: |
8ms |
get forum list: |
20ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
180ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
79ms |
get tp. blocked users: |
2ms |
| others: | 233ms |
| total: | 543ms |

| 0 / 0 |
