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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 14.02.2014, 08:27   #1
victorixx
Пользователь
 
Регистрация: 29.01.2010
Сообщений: 21
По умолчанию Связь двух массивов

Доброго времени суток всем!
Встала тут передо мной задача. Имеется форма, в модуле которой объявляется через запятую два динамических массива - абсолютно одинаковых, примерно так:
Код:
fig, xfig:array of record
   pad:array[1..7] of string;
end;
В процессе работы приложения один из массивов постепенно заполняется, однако для редактирования его элементов пользователем открывается вторая (модальная) форма, типа диалоговое окошко. Дык вот, задача состояла в том, чтобы в случае, если по результатам редактирования пользователь нажмет на кнопку ОК, то все изменения сохранились, а на отмену - соответственно, нет.
Решение казалось элементарным:
Перед показом модальной формы присваиваю второму (временному) массиву значение постоянного массива.
Код:
xfig:=fig;
После этого пользователь в диалоговом окне может редактировать отдельные элементы временного массива, далее, в случае отмены пользователем, просто обнуляю временный массив, а в случае подтверждения - делаю
Код:
fig:=xfig;
Операции присваивания получаются замечательно, но когда дело дошло до отмены изменений, я осознал, что буквально каждое сделанное пользователем изменение элемента временного массива xfig тут же вносит точно такое же изменение в тот же элемент основного массива.
Двести раз перепроверил код модальной формы - ни одного упоминания основного массива в нем точно нет.
Из имеющихся у меня трех учебников по Делфи, все как один говорят, что оператор присваивания вычисляет значение правой части и присваивает его левой части. А также что к одинаковым по параметрам массивам возможно применение оператора присваивания. Всё. Ни о какой последующей связи между операндами нигде ни слова.
Дебаггер показывает, что непосредственно перед операцией присваивания временный массив xfig абсолютно пуст. То есть связь появляется именно в результате присваивания.

В принципе саму эту проблему я решил. Сразу после присваивания увеличил число элементов основного массива на один пустой элемент. Магическая связь разорвалась. Но:
1. Программа стала выполнять два абсолютно бессмысленных с точки зрения ее назначения действия (ведь в случае отмены надо вернуть назад число элементов основного массива).
2. Хотелось бы всё-таки знать, что это было - особенности присваивания для массивов, или я все-таки что-то упустил?
Вот, решил посоветоваться с сообществом. Есть у кого мысли? Мож кто-то встречался с подобным и знает, как с этим бороться? Спасибо заранее.

Последний раз редактировалось victorixx; 14.02.2014 в 08:32.
victorixx вне форума Ответить с цитированием
Старый 14.02.2014, 08:51   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
array of record
При этом присваивание как ты показал может не сработать, ибо такие переменные являются указателями. Убедись:
Код:
var fig, xfig:array of integer;
begin
 Setlength(fig,2); Setlength(xfig,2);
 fig[0]:=1; fig[1]:=2;
 xfig[0]:=3; xfig[1]:=4;
 xfig:=fig;
 xfig[1]:=99;
 Caption:=IntToStr(fig[1]);
end;
Этот пример наглядно показывает твою проблему. xfig:=fig; означает "xfig будет указывать на тот же участок памяти что и fig".
Поэтому в таких случаях делают сериализацию.
Ну самое простое - в цикле попереганять из массива в массив.
А вообще UNDO так не делается. ИМХО. xfig я кстати бы скинул в форму модальную, а не хранил в том же модуле.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 14.02.2014, 08:53   #3
doktor255
Заблокирован
 
Регистрация: 31.03.2011
Сообщений: 976
По умолчанию

Код
Код:
fig:=xfig;
не производит копирования. Ты просто присваиваешь первому массиву ссылку на второй массив (по принципу ярлыка на рабочем столе). Бороться элементарно. Копировать массив поэлементно.
doktor255 вне форума Ответить с цитированием
Старый 14.02.2014, 09:41   #4
victorixx
Пользователь
 
Регистрация: 29.01.2010
Сообщений: 21
По умолчанию

Цитата:
Сообщение от doktor255 Посмотреть сообщение
Ты просто присваиваешь первому массиву ссылку на второй массив (по принципу ярлыка на рабочем столе).
А почему тогда при изменении массива fig связь разрывается? То же самое будет, если fig вообще обнулить. В xfig элементы все все равно останутся.
Цитата:
Сообщение от doktor255 Посмотреть сообщение
Бороться элементарно. Копировать массив поэлементно.
Блин, но я не хочу поэлементно. Неужто никак нельзя два одноразмерных массива синхронизировать друг с дружкой. Может есть команда, чтоб связь разорвать, не изгаляясь над основным массивом?
victorixx вне форума Ответить с цитированием
Старый 14.02.2014, 09:57   #5
victorixx
Пользователь
 
Регистрация: 29.01.2010
Сообщений: 21
По умолчанию

Цитата:
такие переменные являются указателями
Эта мысль у меня сразу возникла. Но, опять же, почему, в случае
Код:
xfig:=fig; fig:=nil;
xfig оставляет в себе все элементы. Значит таки присвоились.
Цитата:
Поэтому в таких случаях делают сериализацию
Только чур не смеяться, но... это как? Массив целиком куда-то сохранить?
Цитата:
А вообще UNDO так не делается
По-моему, такой способ в данном случае - самый простой, учитывая, что могут быть изменены несколько элементов и подэлементов массива. А что, можно сделать еще проще?
victorixx вне форума Ответить с цитированием
Старый 14.02.2014, 11:01   #6
doktor255
Заблокирован
 
Регистрация: 31.03.2011
Сообщений: 976
По умолчанию

Цитата:
Сообщение от victorixx Посмотреть сообщение
То же самое будет, если fig вообще обнулить.
Наверное это происходит потому, что ты обнуляешь не данные, а ссылку на данные. Кстати именно по этой причине не желательно чистить массивы таким методом, так как память не очищается.
Цитата:
Сообщение от victorixx Посмотреть сообщение
Блин, но я не хочу поэлементно.
А то что по другому нельзя, тебе вообще по фиг? Железобетонный подход.
P.S. Копируй ручками, и не выёживайся.

Последний раз редактировалось doktor255; 14.02.2014 в 11:12.
doktor255 вне форума Ответить с цитированием
Старый 17.02.2014, 02:51   #7
victorixx
Пользователь
 
Регистрация: 29.01.2010
Сообщений: 21
По умолчанию

Цитата:
Сообщение от doktor255 Посмотреть сообщение
А то что по другому нельзя, тебе вообще по фиг? P.S. Копируй ручками, и не выёживайся.
Так бы сразу и сказал Вопрос-то о том и был - можно как-нибудь, или ваще никак.
victorixx вне форума Ответить с цитированием
Старый 17.02.2014, 09:19   #8
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Так бы сразу и сказал
Я ж сразу тебе про цикл то намекнул )
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 17.02.2014, 09:22   #9
doktor255
Заблокирован
 
Регистрация: 31.03.2011
Сообщений: 976
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Я ж сразу тебе про цикл то намекнул )
Видать намёк был слишком тонок.
doktor255 вне форума Ответить с цитированием
Старый 19.02.2014, 06:48   #10
victorixx
Пользователь
 
Регистрация: 29.01.2010
Сообщений: 21
По умолчанию

Итог: Сделал цикл и счастлив. Спасибо всем за разъяснения.
victorixx вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
связь двух dblookupcombobox qwertase Общие вопросы Delphi 1 23.06.2011 20:14
Вопрос про связь двух таблиц Vactive Microsoft Office Access 1 27.11.2010 21:33
Связь двух комбобоксов!!! viteyk Компоненты Delphi 13 18.10.2010 14:48
Связь двух таблиц Denmart БД в Delphi 5 19.08.2009 10:58
связь двух таблиц cub Microsoft Office Excel 11 03.08.2009 18:45