дубликация данных в динамических массивах

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

дубликация данных в динамических массивах

Сообщение Сквозняк » 25.12.2014 10:21:01

Код: Выделить всё
var
a,b: array of byte;

begin
setlength(a,10);
setlength(b,10);
b:=a; //после этой строки, проблемы и начинаются
writeln('a[2]=',a[2],' b[2]=',b[2]);
a[2]:=100;
writeln('a[2]=',a[2],' b[2]=',b[2]);
b[3]:=50;
writeln('a[3]=',a[3],' b[3]=',b[3]);
end.

Выхлоп:
Код: Выделить всё
a[2]=0 b[2]=0
a[2]=100 b[2]=100
a[3]=50 b[3]=50

Использовал динамические массивы вместо простых из-за того что их можно сравнивать целиком, но оказалось что они склеиваются и данные потом самопроизвольно перетекают из одного в другой. Это баг или фича?
Сквозняк
энтузиаст
 
Сообщения: 1129
Зарегистрирован: 29.06.2006 22:08:32

Re: дубликация данных в динамических массивах

Сообщение wavebvg » 25.12.2014 11:44:05

Код: Выделить всё
writeln('Address a=',DWord(@a[0]),', Address b=',DWord(@b[0]));

Нда... Кто-то нереально заоптимизировался!
wavebvg
постоялец
 
Сообщения: 355
Зарегистрирован: 28.02.2008 04:57:35

Re: дубликация данных в динамических массивах

Сообщение Sergei I. Gorelkin » 25.12.2014 12:13:21

Это фича, поведение дин. массивов частично напоминает строки: есть счетчик ссылок и присвоение копирует только указатель, но нет копирования при изменении элементов. Если нужно скопировать данные, то пишем "b:=copy(a)", перед этим setlength(b,10) не нужно.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1407
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: дубликация данных в динамических массивах

Сообщение wavebvg » 25.12.2014 12:36:40

Строки ведут себя логичнее, особенно учитывая, что заменив один символ в исходной строке после копирования мы не получаем сюрпизов.

Ага, в документации так и написано, но, если использовать массив в качестве результата функции - то копируется.
Всегда считал, что в словосочетание динамический массив звучит как: динамический массив. Но кто-то считает, что лучше звучит так: динамический массив и этот кто-то писал компилятор...
wavebvg
постоялец
 
Сообщения: 355
Зарегистрирован: 28.02.2008 04:57:35

Re: дубликация данных в динамических массивах

Сообщение dedm0zaj » 25.12.2014 16:32:36

a и b это неявные указатели (или ссылки. кому как удобнее). когда b присваиваем a, то b начинает указывать на массив, на который указывает a.

зы java хорошо это всё объясняет.
dedm0zaj
постоялец
 
Сообщения: 108
Зарегистрирован: 05.10.2012 19:55:20

Re: дубликация данных в динамических массивах

Сообщение hinst » 25.12.2014 19:22:49

этой фиче уже больше 10 лет, динамические массивы так и работали всю жизнь. Динамический массив это набор: [указатель и длина массива]

Добавлено спустя 1 минуту 8 секунд:
а при вызове SetLength выделяется новый кусок памяти
Чтобы получить копию массива, а не указатель на тот же массив, надо просто создать ещё один массив и скопировать в него элементы
Аватара пользователя
hinst
энтузиаст
 
Сообщения: 781
Зарегистрирован: 12.04.2008 18:32:38

Re: дубликация данных в динамических массивах

Сообщение stanilar » 25.12.2014 23:01:55

Sergei I. Gorelkin писал(а):b:=copy(a)


В общем случае, так понимаю, перед этим надо написать "FreeMem(b)".
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: дубликация данных в динамических массивах

Сообщение kazalex » 25.12.2014 23:59:51

stanilar писал(а):В общем случае, так понимаю, перед этим надо написать "FreeMem(b)".

Неправильно понимаешь. Для управляемых типов, к которым динамические массивы безусловно относятся, весь "головняк" (предварительная инициализация нулем, распределение/перераспределение памяти, подсчет ссылок) берет на себя компилятор.
kazalex
постоялец
 
Сообщения: 296
Зарегистрирован: 01.06.2012 14:54:10

Re: дубликация данных в динамических массивах

Сообщение Сквозняк » 26.12.2014 11:20:39

hinst писал(а):этой фиче уже больше 10 лет,

С таким замечательным поисковиком, как на вики freepascal.org, 10 это не срок :mrgreen:

Код: Выделить всё
var
a,b: array of byte;

begin
setlength(a,10);
b:=copy(a);
if a=b then writeln('равно') else writeln('не равно');
end.

Код: Выделить всё
не равно

И зачем компилятор разрешает операцию сравнения, если она не работает - только чтобы узнать слились массивы в один или нет?
Сквозняк
энтузиаст
 
Сообщения: 1129
Зарегистрирован: 29.06.2006 22:08:32

Re: дубликация данных в динамических массивах

Сообщение wavebvg » 26.12.2014 11:44:56

Вообще-то, динамические массивы - это идея и реализация Borland и никакие академические изыскания не помогут.
Но если говорить про "сакральный смысл", то возмущение вполне логично, но толку никакого - синтаксис застолбили, документацию написали.
Как сделали, так и продали... Купил - пользуйся, не нравится не пользуйся.
wavebvg
постоялец
 
Сообщения: 355
Зарегистрирован: 28.02.2008 04:57:35

Re: дубликация данных в динамических массивах

Сообщение bormant » 26.12.2014 15:37:07

Сквозняк,
"не равно" в данном случае означает, что a и b ссылаются на разные области памяти, изменяя элемент массива "a", элементы массива "b" останутся нетронуты, в отличие от:
Код: Выделить всё
var
  a, b: array of byte;
begin
  SetLength(a,10);
  b:=a;
  if a=b then writeln('равно') else writeln('не равно');
  a[1]:=5; WriteLn(b[1]);
end.
Аватара пользователя
bormant
постоялец
 
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Re: дубликация данных в динамических массивах

Сообщение Сквозняк » 26.12.2014 15:55:07

После тестирования оно и так видно, но сделали в Борланде коряво. Для сравнения указателей можно было записать как-нибудь по другому. А вот заоптимизированная операция сравнения содержимого массивов пригодилась бы.
Сквозняк
энтузиаст
 
Сообщения: 1129
Зарегистрирован: 29.06.2006 22:08:32

Re: дубликация данных в динамических массивах

Сообщение bormant » 26.12.2014 19:17:27

Сквозняк,
раз уж для статических массивов a и b сравнение определено только для String, то с чего бы ждать такой семантики от сравнения динамических массивов c и d? Вот в этой-то части они как раз остались последовательны :-)
Аватара пользователя
bormant
постоялец
 
Сообщения: 408
Зарегистрирован: 21.03.2012 11:26:01

Re: дубликация данных в динамических массивах

Сообщение stanilar » 29.12.2014 17:11:42

kazalex писал(а):Неправильно понимаешь.


Если динамический массив - это указатель, то для него правильно писать FreeMem. То , что кое-что берет на себя компилятор, это уже дело вкуса.

Сквозняк писал(а): А вот заоптимизированная операция сравнения содержимого массивов пригодилась бы.


Лучше сделать один тип - массив, и дать возможность делать хелперы к нему, дальше люди уже сами понапишут что им нужно. Будет просто кристально понятно.
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02

Re: дубликация данных в динамических массивах

Сообщение ger0strat » 29.12.2014 21:59:09

Если это вызывает такие негодования, то что мешает перегрузить оператор?
Хотя иной раз, действительно, поведение неочевидно. Особенно для уставшего мозга :D
Сам предпочитаю пользоваться указателями напрямую.
ger0strat
новенький
 
Сообщения: 40
Зарегистрирован: 13.05.2014 19:35:56

След.

Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5

Рейтинг@Mail.ru