Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Копирование динам. массива, подозрение на ошибку 
:(
    Опции темы
lukas
Дата 9.1.2011, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 771
Регистрация: 23.2.2007

Репутация: 3
Всего: 15



Цитата(БелАмор @  9.1.2011,  18:40 Найти цитируемый пост)
Передача параметров без спецификатора, с const, и с var - это три большие разницы... При const, и var не копируется вообще ничего, именно поэтому, в частности, с этими спецификаторами рекомендуют передавать, например, записи... 


Ну с var не копируется, а вот с const рекорды может копировать, проверено на практике, замедление будет существенное.


--------------------
http://code.google.com/p/orionphp/ - opensource скриптовой язык Orion (аналог PHP) для freepascal/delphi.
PM MAIL WWW   Вверх
bems
Дата 9.1.2011, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



lukas, когда это const-рекорды копируются, если они точно не меняются?


--------------------
Обижено школьников: 8
PM MAIL   Вверх
БелАмор
Дата 9.1.2011, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: 5
Всего: 17



Цитата(lukas @  9.1.2011,  20:11 Найти цитируемый пост)
Ну с var не копируется, а вот с const рекорды может копировать, проверено на практике, замедление будет существенное.

Насколько я помню, с const отсутсвие копирования не гарантируется, но компилятор старается по возможности исключить его....

Цитата(Delphist @  9.1.2011,  20:10 Найти цитируемый пост)
Да очень просто - смысл использования var. var для массива зачем? чтобы изменить адрес массива - но это если и нужно то очень редко 

Пока вам нужно менять только значения элементов - всё замечательно, но как только потребуется вызвать SetLength, вся эта благодать тут-же закончится...
Разница будет следующая:

Константа - компилятор выдаст ошибку.
По значению - получим два разных массива.
По ссылке -  всё нормально: изменим оригинальный внешний массив.

Тестовый пример:

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Types;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
var
  Log: String;
  a: TIntegerDynArray;

function GetDynArrInfo(pArr: Pointer): String;
var
  q: Integer;  // Количество ссылок
  l: Integer;  // Количество элементов массива
  pInt: PInteger;
begin
  if pArr = nil then
  begin
    Result := 'Массив пуст';
    Exit;
  end;
  pInt := pArr;
  Dec(pInt);
  l := pInt^;
  Dec(pInt);
  q := pInt^;
  Result := Format('Адрес: %p  Ссылок: %d  Элементов: %d', [pArr, q, l]);
end;

procedure AddToLog(Comment: String; pArr: Pointer);
begin
  Log := Format('%s%s) %s'#13#10, [Log, Comment, GetDynArrInfo(pArr)]);
end;

procedure AddCommentToLog(Comment: String);
begin
  Log := Format('%s%s'#13#10, [Log, Comment]);
end;

  // По значению
procedure TestVal(b: TIntegerDynArray);
begin
  AddCommentToLog('По значению (TestVal)');
  AddCommentToLog('--------------------');

  AddCommentToLog(#13#10'До изменения'#13#10);
  AddToLog('a', a);
  AddToLog('b', b);

  SetLength(b, 5);
  b[0] := 3;

  AddCommentToLog(#13#10'После изменения'#13#10);
  AddToLog('a', a);
  AddToLog('b', b);
end;

  // По ссылке
procedure TestVar(var b: TIntegerDynArray);
begin
  AddCommentToLog('По ссылке (TestVar)');
  AddCommentToLog('--------------------');

  AddCommentToLog(#13#10'До изменения'#13#10);
  AddToLog('a', a);
  AddToLog('b', b);

  SetLength(b, 5);
  b[0] := 3;

  AddCommentToLog(#13#10'После изменения'#13#10);
  AddToLog('a', a);
  AddToLog('b', b);
end;

  // Как константа
procedure TestConst(const b: TIntegerDynArray);
begin
  AddCommentToLog('Как константа (TestConst)');
  AddCommentToLog('--------------------');

  AddCommentToLog(#13#10'До изменения'#13#10);
  AddToLog('a', a);
  AddToLog('b', b);

  // SetLength(b, 5);  // Ошибка!
  b[0] := 3;

  AddCommentToLog(#13#10'После изменения (только элемента, SetLength запрещено)'#13#10);
  AddToLog('a', a);
  AddToLog('b', b);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  Log := '';

  SetLength(a, 1);
  TestVal(a);
  AddCommentToLog(#13#10);

  SetLength(a, 1);
  TestVar(a);
  AddCommentToLog(#13#10);

  SetLength(a, 1);
  TestConst(a);

  ShowMessage(Log);
end;

end.

На выходе имеем:

Код

По значению (TestVal)
--------------------

До изменения

a) Адрес: 00A75078  Ссылок: 2  Элементов: 1
b) Адрес: 00A75078  Ссылок: 2  Элементов: 1

После изменения

a) Адрес: 00A75078  Ссылок: 1  Элементов: 1
b) Адрес: 00A8A9A8  Ссылок: 1  Элементов: 5


По ссылке (TestVar)
--------------------

До изменения

a) Адрес: 00A75078  Ссылок: 1  Элементов: 1
b) Адрес: 00A75078  Ссылок: 1  Элементов: 1

После изменения

a) Адрес: 00A50C48  Ссылок: 1  Элементов: 5
b) Адрес: 00A50C48  Ссылок: 1  Элементов: 5


Как константа (TestConst)
--------------------

До изменения

a) Адрес: 00A50C48  Ссылок: 1  Элементов: 1
b) Адрес: 00A50C48  Ссылок: 1  Элементов: 1

После изменения (только элемента, SetLength запрещено)

a) Адрес: 00A50C48  Ссылок: 1  Элементов: 1
b) Адрес: 00A50C48  Ссылок: 1  Элементов: 1


Это сообщение отредактировал(а) БелАмор - 10.1.2011, 09:27
PM   Вверх
Delphist
Дата 10.1.2011, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphist Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2145
Регистрация: 3.2.2004
Где: всегда в сети

Репутация: 2
Всего: 3



Цитата(БелАмор @  9.1.2011,  23:47 Найти цитируемый пост)
Пока вам нужно менять только значения элементов - всё замечательно, но как только потребуется вызвать SetLength, вся эта благодать тут-же закончится...
Разница будет следующая:

Ну var, это тот же аналог что если я передам через указатель

Код

procecdure Foo1(var Arr: TDynArrOfInt);
begin
end;

procedure Foo2(pArr: PDynArrOfInt)
begin
end;


var
   Arr: TDynArrOfInt;


Foo1(Arr);
Foo2(@Arr)

Foo1 и Foo2 это эквивалент


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
БелАмор
Дата 10.1.2011, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: 5
Всего: 17



Цитата(Delphist @  10.1.2011,  13:37 Найти цитируемый пост)
Ну var, это тот же аналог что если я передам через указатель

Да, это аналог. Но в случае явного использования указателя появляется два лишних шага: взятие адреса и последующее разуказачивание. Всё это затуманивает смысл. Кроме того, есть вещи, которые делать просто "не принято". В отношении некоторых из них это вполне обосновано. В отношении других - не очень. Но считаться с этим приходится.
PM   Вверх
bems
Дата 10.1.2011, 19:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 31
Всего: 88



Цитата(БелАмор @  9.1.2011,  22:47 Найти цитируемый пост)
Насколько я помню, с const отсутсвие копирования не гарантируется, но компилятор старается по возможности исключить его....
А насколько я помню, копируется только когда рекорд влазит в 4 байта, но тут нет никакого замедления (исключение - inline-подпрограммы, с которыми все иначе)



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1129 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.