Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2010.10.03;
Скачать: [xml.tar.bz2];

Вниз

Как скопировать один массив массивов в другой?   Найти похожие ветки 

 
AKE   (2010-07-02 19:12) [0]

сабж.


 
Amoeba_   (2010-07-02 19:22) [1]

Какой? Статический или динамический?


 
AKE   (2010-07-02 19:36) [2]

статический массив статических массивов...


 
Германн ©   (2010-07-02 20:02) [3]

Move


 
AKE   (2010-07-02 20:29) [4]

Германн ©   (02.07.10 20:02) [3]
Спасибо...


 
Jeer ©   (2010-07-02 21:51) [5]

Вообще-то, для статических массивов одинаковой размерности

A := B;

означает копирование содержимого А в B.

Для динамических же - копирование адреса.


 
AKE   (2010-07-02 21:57) [6]

Jeer ©   (02.07.10 21:51) [5]
А если это массив массивов то всё перекопируется нормально...


 
Jeer ©   (2010-07-02 22:09) [7]


> AKE   (02.07.10 21:57) [6]
>
> Jeer ©   (02.07.10 21:51) [5]
> А если это массив массивов то всё перекопируется нормально.
> ..


Непонятно, это вопрос или утверждение ?


 
AKE   (2010-07-02 22:44) [8]

Jeer ©   (02.07.10 22:09) [7]
Знак вопроса забыл поставить...


 
Германн ©   (2010-07-03 01:43) [9]


> А если это массив массивов

Для статических массивов это не имеет ни малейшего значения. Во всяком случае, если оба массива одного типа (соломку всё-таки решил подстелить :).


 
Anatoly Podgoretsky ©   (2010-07-03 13:42) [10]

> Германн  (03.07.2010 01:43:09)  [9]

Не обязательно, но копируемый массив должен быть такого же или меньшего
объема.


 
Демо ©   (2010-07-03 16:53) [11]

Как для динамических, так и для статических массивов, достаточно выполнить:

B := A;

для динамического массива, кроме этого, нужно ещё выполнить

SetLength(B,Length(B));


 
Jeer ©   (2010-07-03 17:16) [12]


> Демо ©   (03.07.10 16:53) [11]


Иди покури "травку", прежде чем советовать.


 
Jeer ©   (2010-07-03 17:18) [13]

arsA,arsB: array[0..4] of double;
 ardA, ardB: array of double;

 SetLength(ardA, 5);
 SetLength(ardB, 5);

 arsA[0] := 1;
 arsB := arsA;
 arsB[0] := 2;
 ShowMessage(Format("%f %f",[arsA[0], arsB[0]]));

 ardA[0] := 1;
 ardB := ardA;
 ardB[0] := 2;
 ShowMessage(Format("%f %f",[ardA[0], ardB[0]]));

Как говорится -"Почувствуй разницу"


 
Amoeba_   (2010-07-03 17:18) [14]


> Демо ©   (03.07.10 16:53) [11]


> для динамического массива, кроме этого, нужно ещё выполнить
>
> SetLength(B,Length(B));

Не надо.
Читаем справку:
If X and Y are variables of the same dynamic-array type, X :=Y points X to the same array as Y. (There is no need to allocate memory for X before performing this operation.)


 
Anatoly Podgoretsky ©   (2010-07-03 17:25) [15]

> Amoeba_  (03.07.2010 17:18:14)  [14]

Не надо это слишком мягко сказано, это просто вредно, ведь придется сначала
выделить, потом освободить память, потом присвоить указатель.


 
Jeer ©   (2010-07-03 17:25) [16]

Вкупе, вот такие операции породят утечку, т.к. будет утеряна ссылка на В и ее инициализация (аллокация).

SetLength(ardB, 5);
arsB := arsA;


 
Jeer ©   (2010-07-03 17:27) [17]

P.S.
Возможно, что средства управления динамическими массивами действительно "подчистят" B, но я не уверен.
Потому это не небрежность, а ошибка.


 
Демо ©   (2010-07-03 17:47) [18]


> Jeer ©   (03.07.10 17:16) [12]
> > Демо ©   (03.07.10 16:53) [11]Иди покури "травку", прежде
> чем советовать.


Бредить не надо? Ок?


> Amoeba_   (03.07.10 17:18) [14]
> > Демо ©   (03.07.10 16:53) [11]> для динамического массива,
>  кроме этого, нужно ещё выполнить> > SetLength(B,Length(B));
> Не надо.Читаем справку:If X and Y are variables of the same
> dynamic-array type, X :=Y points X to the same array as
> Y. (There is no need to allocate memory for X before performing
> this operation.)


При присвоении переменных динамических массивов происходит копирование ссылки на массив.
+ Рекомендую перечитать справку по SetLength.

procedure TForm1.btnCopyDinArraysClick(Sender: TObject);
type
 TTestArr = array of byte;
var
 vB1: TTestArr;
 vB2: TTestArr;
begin
 SetLength(vB1, 3);
 vB1[0] := 1;
 vB1[1] := 2;
 vB1[2] := 3;

 vB2 := vB1;
 SetLength(vB2, Length(vB2)); //Здесь память будет перераспределена и все элементы скопированы.

 vB1[0] := 10;
end;


 
Демо ©   (2010-07-03 17:50) [19]


> Anatoly Podgoretsky ©   (03.07.10 17:25) [15]


Анатолий,Ю я бы советовал всё же внимательнее читать, то, что пишут.
У меня написано в [11], что SetLength должен выполняться после присвоения.


 
Anatoly Podgoretsky ©   (2010-07-03 18:07) [20]

А ты тоже повнимательнее читай, особенно про A:=B; Если после то это особо жестоко, это тянет на пожизненый эцик с гвоздями


 
Демо ©   (2010-07-03 18:12) [21]


>  особенно про A:=B;


Э-э... У меня написано B := A;


 
Anatoly Podgoretsky ©   (2010-07-03 19:47) [22]

> Демо  (03.07.2010 18:12:21)  [21]

Ну тогда другое дело.


 
Германн ©   (2010-07-04 01:44) [23]


> Anatoly Podgoretsky ©   (03.07.10 13:42) [10]
>
> > Германн  (03.07.2010 01:43:09)  [9]
>
> Не обязательно, но копируемый массив должен быть такого
> же или меньшего
> объема.
>

Тогда возникает вопрос о "правильности" копирования.
Например массив A : array [0..N-1][0..N-1][0..N-1] of Byte  меньше по объёму чем массив B : array [0..M-1][0..M-1] of Byte если N < 2/3 от M. Но что тогда будет после B:=A?


 
Юрий Зотов ©   (2010-07-04 01:50) [24]

Не въезжаю, о чем спор?

B := A; // Копируется только указатель.
SetLength(B, Length(B)); // Создается реальная копия массива

С этого момента A указывает на старый массив, B - на новый. О каких утечках памяти идет речь?


 
Германн ©   (2010-07-04 02:08) [25]


> Юрий Зотов ©   (04.07.10 01:50) [24]
>
> Не въезжаю, о чем спор?
>
>

Так ведь в начале были статические массивы.


 
Демо ©   (2010-07-04 02:52) [26]


> Но что тогда будет после B:=A?


Будет Incompatible types при компиляции.


 
Германн ©   (2010-07-04 02:56) [27]


> Демо ©   (04.07.10 02:52) [26]
>
>
> > Но что тогда будет после B:=A?
>
>
> Будет Incompatible types при компиляции.

Ну а я про что?


 
Германн ©   (2010-07-04 03:00) [28]

И при чём тут "объём" массива?


 
Anatoly Podgoretsky ©   (2010-07-04 11:40) [29]

> Германн  (04.07.2010 01:44:23)  [23]

Массив будет частично запонлнен, но массив А будет скопирован полностью.
Хуже если А > B, вот тогда капут.
В массиве будет M*M элементов и это число надо хранить, что бы можно было
работать с частично заполненым массивов. Вообще то это обычная ситуация,
когда размер массива больше, чем число элементов, правда обычно эту технику
используют для одномерных массивов.

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


 
Anatoly Podgoretsky ©   (2010-07-04 11:50) [30]

> Юрий Зотов  (04.07.2010 01:50:24)  [24]

> С этого момента A указывает на старый массив, B - на новый.

Это не строки и операция COPY-ON-WRITE не применима к ним, к ним применим
только счетчик ссылок, по обнулению массив освобождается

> Unlike strings and static arrays, COPY-ON-WRITE is not employed for
> dynamic arrays, so they are not automatically copied before they are
> written to.

>   A[0] := 1;
>   B := A;
>   B[0] := 2;
> end;

> the value of A[0] is 2. (If A and B were static arrays, A[0] would still
> be 1.) и тоже для строк, A[1] будет иметь старое значение
> Assigning to a dynamic-array index (for example, MyFlexibleArray[2] := 7)
> does not reallocate the array.


 
Anatoly Podgoretsky ©   (2010-07-04 11:52) [31]

> Германн  (04.07.2010 03:00:28)  [28]

А ты налей два литра в литровую тару.


 
Sha ©   (2010-07-04 12:07) [32]

> Демо ©   (03.07.10 16:53) [11]
> Как для динамических, так и для статических массивов, достаточно выполнить:
> B := A;
> для динамического массива, кроме этого, нужно ещё выполнить
> SetLength(B,Length(B));

Небольшое добавление.
В случае автора (массив массивов) после присваивания оператор
SetLength(B,Length(B));
надо заменить на что-то вроде
SetLength(B,Length(B),Length(B[0]));

Здесь предполагается, что динамический массив двумерный и прямоугольный.


 
Демо ©   (2010-07-04 14:23) [33]


> > С этого момента A указывает на старый массив, B - на новый.
>  Это не строки и операция COPY-ON-WRITE не применима к ним,
>  к ним применим только счетчик ссылок, по обнулению массив
> освобождается


Весь цимус в использованиии SetLength. SetLength выделяет под массив память и копирует туда данные из исходного массива.
При этом ссылка на массив становится уникальной.

PS.

Статические же массивы возможно копировать только в случае идентичности типов. Ни о какой различной размерности целевого исходного массива речи быть не может.


 
Sapersky   (2010-07-04 15:18) [34]

В случае автора (массив массивов) после присваивания оператор
SetLength(B,Length(B));
надо заменить на что-то вроде
SetLength(B,Length(B),Length(B[0]));


Я для таких случаев написал функцию UniqueData, по аналогии с UniqueString.
http://sapersky.narod.ru/files/TypInfoEx.rar


 
Демо ©   (2010-07-04 15:31) [35]


> Sapersky   (04.07.10 15:18) [34]


Универсализм - враг эффективности и простоты кода.


 
Sapersky   (2010-07-04 17:29) [36]

Копипаст "простых и эффективных" решений тоже сомнительное благо - при этом легко ляпнуть идиотскую ошибку и потом долго её искать.
Истина, видимо, посередине, с отклонениями (по вкусу) в ту или иную сторону.

Конкретно TypInfoEx затраченных на неё усилий не оправдала (кроме той части, которая относится к массивам), получился скорее хакерский концепт-юнит, чем "рабочая лошадка". Но если уж написано - то почему бы не воспользоваться. По крайней мере, для многомерных массивов и пр. сложных структур; хотя и для одномерных SetLength(B,Length(B)) куда больше смахивает на шаманское заклинание, чем UniqueData.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2010.10.03;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.004 c
15-1278389451
Думкин
2010-07-06 08:10
2010.10.03
Где летающие скейты?


2-1278810092
defen
2010-07-11 05:01
2010.10.03
объединение приложения и сервиса


11-1224681119
dron9999
2008-10-22 17:11
2010.10.03
не могу установить компонент


15-1278348746
SemNic
2010-07-05 20:52
2010.10.03
Могут ли быть проблемы в WIN7 при эксплуатации для проги


11-1224845500
Кто б сомневался
2008-10-24 14:51
2010.10.03
Аналог Timage для PNG - положить картинку на форму





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский