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

Поиск:

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


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


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

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



Вопрос: 
Будет ли корректно скопирован массив а в массив b, и не возникнет ли ситуация, что по выходу из Foo в массиве b окажутся левые данные, т.к. массив a 
локальная переменная, а b всего лишь указатель на нее?
Код

type
  PDynArrOfInt = ^TDynArrOfInt;
  TDynArrOfInt = array of Integer;

procedure TForm1.Foo(b: PDynArrOfInt);
var
  a: TDynArrOfInt;
begin

  SetLength(a, 3);
  a[0] := 1; a[1] := 2; a[2] := 3;
  b^ := a;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  b: TDynArrOfInt;
begin

  Foo(@b);
end;


Это сообщение отредактировал(а) Delphist - 9.1.2011, 13:34


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


   ☽
***


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

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



При присваивании
Цитата(Delphist @  9.1.2011,  16:31 Найти цитируемый пост)
Код
b^ := a;

счетчик ссылок на массив a будет увеличен на 1. Легко проверить:
Код

procedure TForm1.Foo(b: PDynArrOfInt);
var
  a: TDynArrOfInt;
begin
  SetLength(a, 3);
  a[0] := 1; a[1] := 2; a[2] := 3;
  ShowMessage(IntToStr(Integer(Pointer(Integer(@a[0]) - 8)^))); // 1 ссылка — a
  b^ := a;
  ShowMessage(IntToStr(Integer(Pointer(Integer(@a[0]) - 8)^))); // 2 ссылки — a и b
end;


При выходе из процедуры счетчик ссылок уменьшится на 1, но не будет равен 0, поскольку внешняя b ссылается на него, поэтому массив не будет освобожден, и данные будут корректны.
PM   Вверх
Delphist
Дата 9.1.2011, 14:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Amphiluke @  9.1.2011,  15:30 Найти цитируемый пост)
При выходе из процедуры счетчик ссылок уменьшится на 1, но не будет равен 0, поскольку внешняя b ссылается на него, поэтому массив не будет освобожден, и данные будут корректны. 

Т.е. массив а выделяется не в памяти локального стека Foo?

Добавлено через 4 минуты и 59 секунд
а счетчик ссылок судя из кода храниться по адресу где был выделен массив со смещением на 8 байт? 


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


Опытный
**


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

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



Вот так правильно:

Код

type
  PDynArrOfInt = ^TDynArrOfInt;
  TDynArrOfInt = array of Integer;
procedure TForm1.Foo(var b: TDynArrOfInt);
var
  a: TDynArrOfInt;
begin
  SetLength(a, 3);
  a[0] := 1; a[1] := 2; a[2] := 3;
  b^ := copy(a,0,length(a));
end;
procedure TForm1.Button1Click(Sender: TObject);
var
  b: TDynArrOfInt;
begin
  Foo(b);
end;


Это сообщение отредактировал(а) lukas - 9.1.2011, 14:51


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


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


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

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



А интерфейсы в delphi по этому же принципу работают, в смысле тоже счетчик создается?

Я так понимаю это что-то из серии garbage collection

Добавлено @ 14:51
Цитата(lukas @  9.1.2011,  15:50 Найти цитируемый пост)
Вот так правильно:

не совсем, твой способ медленнее


Это сообщение отредактировал(а) Delphist - 9.1.2011, 14:54


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


   ☽
***


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

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



Цитата(Delphist @  9.1.2011,  17:38 Найти цитируемый пост)
Т.е. массив а выделяется не в памяти локального стека Foo?

Ну, если не ошибаюсь, память под динамические массивы выделяется из «кучи», так что существование динамического массива за пределами локальной области видимости процедуры нормально.

Цитата(Delphist @  9.1.2011,  17:38 Найти цитируемый пост)
а счетчик ссылок судя из кода храниться по адресу где был выделен массив со смещением на 8 байт? 

Угу.
PM   Вверх
Delphist
Дата 9.1.2011, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Amphiluke @  9.1.2011,  16:03 Найти цитируемый пост)
Ну, если не ошибаюсь, память под динамические массивы выделяется из «кучи», так что существование динамического массива за пределами локальной области видимости процедуры нормально.

А как считаешь какой способ копирования лучше, то что я написал или же что lukas, 


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


Опытный
**


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

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



Delphist 

Copy функция работает с массивами, она довольно быстрая, а то что ты привел, это не копирование, так вообще вроде не делают. Ты правильно используешь ссылку на массив, создав тип PDynArrOfInt, вот и его везде и используй, а T* не используй вообще (если не хочешь копирования).


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


Бывалый
*


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

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



Цитата(Delphist @  9.1.2011,  13:31 Найти цитируемый пост)
type
  PDynArrOfInt = ^TDynArrOfInt;

Забудьте о типе "указатель на динамический массив".
Переменная типа "динамический массив" - это уже указатель.

Цитата(Delphist @  9.1.2011,  14:38 Найти цитируемый пост)
Т.е. массив а выделяется не в памяти локального стека Foo?

Переменная - локальная, но ссылается на данные в куче.

Цитата(Delphist @  9.1.2011,  14:38 Найти цитируемый пост)
а счетчик ссылок судя из кода храниться по адресу где был выделен массив со смещением на 8 байт?

Да. Подробнее смотрите моё сообщение по ссылке:
http://www.delphikingdom.com/asp/answer.asp?IDAnswer=62357

Если написать
  a := b;
то a и b будут ссылаться на одни и те-же данные в куче. 
Принципальная разница между строками и динамическими массивами состоит в следующем:
Для строк при изменении данных через одну из переменных, захватывается новая память и модифицируется копия, после чего указатели будут ссылаться уже на разные данные.
Для динамических массивов такого перезахвата не производится, и при изменении данных через одну переменную, изменяться будут и данные, читаемые через другую, т.к. эти переменные будут продолжать ссылаться на одни и те-же данные.

Если интересно про строки, можете посмотреть мой пример здесь:
http://www.delphikingdom.com/asp/articles_...?ArticleID=1206

PM   Вверх
Delphist
Дата 9.1.2011, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Я объясню зачем такое нужно, например, мы передаем такую структуру:
Код

type 
TRawGroup  = record
....
end;
TDynArrOfRawGroups = array of TRawGroup;
PDynArrOfRawGroups = ^TDynArrOfRawGroups;

PStructrura = ^TStructura;
TStructora = recrod
ParentGroup: integer;
RawGroups: TDynArrOfRawGroups;
end;

procedure TMyClass.MyMethod(pStructura: PStructura);
var
   RawGroups: TDynArrOfRawGroups;
begin

   //здесь что-то делаем и затем заполняем данными RawGroups, а затем вот это:
  if Length(RawGroups) then
  begin 
     SetLength(pStructura^, Length(pStructura^) + 1);
     pStructura^[High(pStructura^)].RawGroups := RawGroups;
  end;
end;

procedure TMyClass.MyMethod(pStructura: TStructura);
begin

    SetLength(pStructura^, Length(pStructura^) + 1);
 
   //здесь что делаем заполняющая данные pStructura^[High(pStructura^)].RawGroups напрямую:
   ...

   //но  я не хочу, чтобы создавался новый элемент в pStructura^, если Length(RawGroups) окажется равным нулю

end;


Добавлено @ 16:34
Цитата(БелАмор @  9.1.2011,  17:18 Найти цитируемый пост)
Для динамических массивов такого перезахвата не производится, и при изменении данных через одну переменную, изменяться будут и данные, читаемые через другую, т.к. эти переменные будут продолжать ссылаться на одни и те-же данные.

Не правда, если сделать так:
Код

  SetLength(a, 3);
  a[0] := 1; a[1] := 2; a[2] := 3;
  b^ := a;
  SetLength(b^, 3);
  a[0] := 4;

  //здесь уже b[0] <> a[0]


И вот для таких то случаев, в локальные процедуры массив лучше передавать через указатель

Это сообщение отредактировал(а) Delphist - 9.1.2011, 16:38


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


Бывалый
*


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

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



Цитата(Delphist @  9.1.2011,  16:31 Найти цитируемый пост)
Не правда, если сделать так:  SetLength(a, 3);
  a[0] := 1; a[1] := 2; a[2] := 3;
  b^ := a;
  SetLength(b^, 3);
  a[0] := 4;

  //здесь уже b[0] <> a[0]

Я допустил неточность. Я имел в виду изменение отдельных элементов массива без изменения длины самого массива.
В случае вызова SetLength, естественно, происходит перезахват памяти и переменные уже будут ссылаться на разные данные.

Цитата(Delphist @  9.1.2011,  16:31 Найти цитируемый пост)
И вот для таких то случаев, в локальные процедуры массив лучше передавать через указатель

Для таких случаев массив в процедуру следует передавать как var-параметр. А внутри процедуры можно либо работать напрямую с оригинальным массивом, либо завести локальный, работать с ним, а потом присвоить переданной перменной.
Кстати, обратите внимание на модуль Types
Там, в частности, уже объявлен тип:
TIntegerDynArray = array of Integer;

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

Код

procedure Foo1(var b: TIntegerDynArray);
var
  a: TIntegerDynArray;
begin
  SetLength(a, 3);
  a[0] := 1;
  a[1] := 2;
  a[2] := 3;

  b := a;
end;

procedure Foo2(var b: TIntegerDynArray);
begin
  SetLength(b, 3);
  b[0] := 1;
  b[1] := 2;
  b[2] := 3;
end;

PM   Вверх
Delphist
Дата 9.1.2011, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



var для динам. массивов в параметрах функции вообще нет смысла использовать!

Это сообщение отредактировал(а) Delphist - 9.1.2011, 17:47


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


Опытный
**


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

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



Цитата(Delphist @  9.1.2011,  17:46 Найти цитируемый пост)
var для динам. массивов в параметрах функции вообще нет смысла использовать!


Если там будет const или без (не помню), будет происходить постоянное копирование массива перед вызовом, я проверял.



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


Бывалый
*


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

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



Цитата(Delphist @  9.1.2011,  17:46 Найти цитируемый пост)
var для динам. массивов в параметрах функции вообще нет смысла использовать!

Хм... Почему? Хотя бы минимальное обоснование... Вы точно не путаете с классовыми переменными?

Цитата(lukas @  9.1.2011,  18:05 Найти цитируемый пост)
Если там будет const или без (не помню), будет происходить постоянное копирование массива перед вызовом, я проверял.

Передача параметров без спецификатора, с const, и с var - это три большие разницы... При const, и var не копируется вообще ничего, именно поэтому, в частности, с этими спецификаторами рекомендуют передавать, например, записи...
PM   Вверх
Delphist
Дата 9.1.2011, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(БелАмор @  9.1.2011,  19:40 Найти цитируемый пост)
Хм... Почему?


Да очень просто - смысл использования var. var для массива зачем? чтобы изменить адрес массива - но это если и нужно то очень редко


--------------------
ProcessInfo 1-ая моя программа (аналог spyxx.exe с гораздо большим функц-ом - внедрение dll в адр. простр. процесса, перехват API-функций, разбор приложения на окна мн.др).
Когда-то давным-давно использовал это...
PM MAIL ICQ   Вверх
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   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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