Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.17;
Скачать: CL | DM;

Вниз

Работа с динамической памятью и указателями   Найти похожие ветки 

 
Lucky[ELF]   (2004-02-01 23:04) [0]

Доброго времени суток! Подскажите пожалуйста как работать с динамической памятью.

Вместо предисловия: я пишу на разных языках и так уж случилось, что Си я знаю лучше всего, но хотелось бы иметь навыки в Дельфях не меньшии. Работу со списками я начал изучать с Паскаля, поскольку так решил препод, параллельно я делал это на Сях, по выше указанной причине. До сих пор со списками проблем не было ни в одном из двух языков. А не так давно я писал динамическое хранилище на С++ - написал и все получилось и тут у меня всал вопрос как такое же реализовать на Пасе/Делфях?

Вопрос конкретно в следующем:
на Сях/С++ я написал такую функцию

int CVault ::CreateItem( void *pData, word dSize, eVaultType_t vType )
{
VaultItem_t *pItem, *newItem = new( VaultItem_t );

if ( !newItem ) // Ошибка, неудалось выделить память
return -1;

newItem->data = (byte *)new byte [dSize]; // Выделяем место под данные

if ( !newItem->data ) // Если память выделеть не удалось
{
delete newItem; // Освобождаем то под что, выделить удалось
return -1; // Выход с ошибкой
}
memcpy( newItem->data, pData, dSize ); // Копируем данные

newItem->dataSize = dSize; // Запоминаем размер данных
newItem->ID = lastID++; // Генерим ID
newItem->next = NULL; // Следующего пока нет

// Подцепляем созданный элемент к списку
if ( !rootItem )
rootItem = newItem;
else
{
if ( !vType ) // Вставка в начало списка
{
// Реализация списка
newItem->next = rootItem;
rootItem = newItem;
}
else // Вставка в конец списка
{
// Реализация очереди
pItem = rootItem;
while( pItem->next != NULL )
pItem = pItem->next;

pItem->next = newItem;
}
}

maxItem++; // Счетчик очереди надо увеличить
return newItem->ID; // Все прошло успешно
}


Вот далее для ее использования

vMainMenu.CreateItem (&newItem, sizeof (newItem));

поясню тут:
newItem - область памяти которую нужно сохранить, это может быть все что угодно - массив, структура, объединение, переменная.

sizeof (newItem) - соответсвенно объем этих данных

Вопрос как реализовать это на Дельфях?
т.е. конкретные места которые у меня вызываеют непонимание - это как передать любые данные в функцию и как эти данные скопировать в выделенную память? и еще чем выделять память
procedure New(var P: Pointer);
procedure Dispose(var P: Pointer);

или
procedure FreeMem(var P: Pointer[; Size: Integer]);
procedure GetMem(var P: Pointer; Size: Integer);

или есть еще какие нибудь?

Заранее спасибо! С уважением Lucky[ELF]!

ЗюЫю можно ссылки на ресурсы.


 
Юрий Зотов ©   (2004-02-02 00:40) [1]

Вот пример построения классического связанного списка (писал прямо здесь и не проверял, поэтому возможны ошибки, но для того, чтобы показать принципы, думаю, это неважно).

type
PItem = ^TItem;
TItem = record // или packed record
... // произвольный набор полей
NextItem: PItem
end;

var
FirstItem: PItem = nil;

procedure CreateNewItem;
var
LastItem: PItem;
begin

// Если списка еще нет, то создаем его первый элемент
if FirstItem = nil then
begin
New(FirstItem);
FirstItem^.NextItem := nil; // Признак последнего элемента
Exit
end

// Ищем последний элемент списка
LastItem := FirstItem;
while LastItem^.NextItem <> nil do
LastItem := LastItem^.NextItem;
// Создаем новый элемент и добавляем его в конец списка.
// Этому новому элементу ставим признак последнего.
New(LastItem^.NextItem);
LastItem^.NextItem^.NextItem := nil

end;

procedure DeleteAllItems;
var
P: PItem;
begin
while FirstItem <> nil do
begin
P := FirstItem^.NextItem;
Dispose(FirstItem);
FirstItem := P
end
end;


 
Lucky[ELF]   (2004-02-02 21:58) [2]

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

int CVault ::CreateItem( void *pData, word dSize, eVaultType_t vType )
{
VaultItem_t *pItem, *newItem = new( VaultItem_t );

if ( !newItem ) // Ошибка, неудалось выделить память
return -1;

newItem->data = (byte *)new byte [dSize]; // Выделяем место под данные

if ( !newItem->data ) // Если память выделеть не удалось
{
delete newItem; // Освобождаем то под что, выделить удалось
return -1; // Выход с ошибкой
}
memcpy( newItem->data, pData, dSize ); // Копируем данные


 
jack128 ©   (2004-02-02 22:10) [3]

короче прямой перевод на Object pascal
functiom CVault.CreateItem(pData: Pointer;dSize: word; vType: eVaultType_t): integer;
var
pItem, newItem: ^VaultItem_t;
begin
New(newItem);
if newItem = nil then // Ошибка, неудалось выделить память
begin
Result := -1;
Exit;
end;
newItem^.data = AllocMem(dSize); // Выделяем место под данные
if newItem^.data <> nil then // Если память выделеть не удалось
begin
Dispose(newItem); // Освобождаем то под что, выделить удалось
Result := -1; // Выход с ошибкой
end;
memcpy(newItem^.data, pData, dSize ); // Копируем данные


 
jack128 ©   (2004-02-02 22:14) [4]

мда. Что то мя глюкнуло
вместо memcpy используй Move.
Move(pData^, newItem^.Data^, dSize);


 
Lucky[ELF]   (2004-02-02 23:43) [5]

Вот это уже лучше, обязательно попробую. Спасибо.

А есть ли возможность добраться до до определенной ячейки -ну типа как в массиве, сишка это дело понимает просто arr[index], а как такое реализуется в Дельфях?

А Move он копирует или перемещаяет?

И последнее как будет выглядет вызов этой функции?

ItemID := CVault.CreateItem (@vRec, sizeof(vRec), eList );

инересует момент передачи указателя - надо писать @ или нет? или это как-то по другому?

Спасибо! с уважением!


 
jack128 ©   (2004-02-02 23:50) [6]


> добраться до до определенной ячейки -ну типа как в массиве,
> сишка это дело понимает просто arr[index], а как такое реализуется
> в Дельфях
если arr - массив, то точно так же.


> А Move он копирует или перемещаяет?
а это не одно и тоже? ;-)


> И последнее как будет выглядет вызов этой функции?
>
> ItemID := CVault.CreateItem (@vRec, sizeof(vRec), eList
> );
именно так и выглядит.
И последнее: завтра, с утра идешь в магазин и покупаешь книжку по языку Object Pascal ;-)


 
Юрий Зотов ©   (2004-02-03 12:38) [7]

> Lucky[ELF]

Я думал, что у Вас есть вопросы по принципам. Оказалось, что они у Вас всего лишь по синтаксису. Сорри, но это несерьезно.

P.S.
За исключением одного вопроса - Move он копирует или перемещает. Который и не по синтаксису, и не по принципам, а по азбуке.


 
Lucky[ELF] ©   (2004-02-03 18:58) [8]


> jack128 © (02.02.04 23:50) [6]
>
> > добраться до до определенной ячейки -ну типа как в массиве,
>
> > сишка это дело понимает просто arr[index], а как такое
> реализуется
> > в Дельфях
> если arr - массив, то точно так же.


Нет это не массив, arr - это указатель на область памяти, например как это ->
newItem^.data = AllocMem(dSize); // Выделяем место под данные

В том то и прикол, что в Сях выделив память динамически можно "перелапатить" ее как массив, интересно как это выполнить на пасе, на сишке также это можно делать и через указатель (*pMem + x <-> pMem[x]) - в пасе должно быть что-то тоже.


> > А Move он копирует или перемещаяет?
> а это не одно и тоже? ;-)

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


> И последнее: завтра, с утра идешь в магазин и покупаешь
> книжку по языку Object Pascal ;-)


Ни за что! тем более по пасу! причина - просто не вижу особой необходимости, хотел было купить книгу по Delphi7+DataBase, но и на ту денег зажал ("еврейская" натура взяла свое).
нет надобности по той причине, что обычно пишу на Сях, но иногда требуется именно на Дельфях, а так как привых к Сям, то привык к его возможностям - и не знаю как некоторые выполнить на Пасе (память и указатели как раз одно из)

"Язык формирует наш способ мышления и определяет, о чем мы можем мыслить."
- Б.Л. Ворф


> Юрий Зотов © (03.02.04 12:38) [7]
> > Lucky[ELF]
>
> Я думал, что у Вас есть вопросы по принципам. Оказалось,
> что они у Вас всего лишь по синтаксису. Сорри, но это несерьезно.



Напрасно вы думаете, что это не серьезно, подобно тому как ... (см. цитату) в языке еще ОЧЕНЬ важно знать, что МОЖНО и как это выполнить а иначе никуда - это еще на первом курсе произнес мой учитель по asm"у, но я тогда тупо смотря на доску не обратил на нее внимания! :)

> P.S.
> За исключением одного вопроса - Move он копирует или перемещает.
> Который и не по синтаксису, и не по принципам, а по азбуке.


:))))
Моя глупость, моя.

Спасибо за разъяснения! так глядишь и ума наберусь.
С уважением Lucky[ELF]


 
Romkin ©   (2004-02-03 19:07) [9]

А в Delphi обычно очень мало работают с динамической памятью явно.
string & dynamic array рулят.
Например, объявляешь

type
TMyArray = array of integer;

var
MyArray: TMyArray;

begin
SetLength(MyArray, 300); //Все, есть массив от 0 до 299
//работаем с ним
end; //А вот уничтожится он, как только выйдет из области видимости

То же самое со string, только у них еще и счетчик копий есть


 
Lucky[ELF] ©   (2004-02-03 19:57) [10]


> Romkin © (03.02.04 19:07) [9]


Вот это вообще новости! обязательно возьму на заметку, так все просто, что аж не по себе!

А если дальше этот массивчик передать надо в процедуру или функцию или вернуть тогда как быть?


 
Romkin ©   (2004-02-03 20:04) [11]

Да я тут сегодня в Медии писал буквально следующее:

TCurveArray = array of TPoint;

function TCurves.PointArray(Index: integer): TCurveArray;
var
Curr: PCurve;
i, len: integer;
begin
Result := nil;
Curr := GetCurve(Index);
len := 0;
while assigned(Curr) do
begin
inc(len);
Curr := Curr^.Next;
end;
if len = 0 then exit;
SetLength(Result, len); //фактически выделяем память
Curr := GetCurve(Index);
for i := High(Result) downto Low(Result) do
with Result[i] do
begin
X := Curr^.X;
Y := Curr^.Y;
Curr := Curr^.Next;
end;
end;

//юзаем:
var
CurveArray: TCurveArray;

for CurveIndex := 0 to FCurves.Count - 1 do
with pbCurve.Canvas do
begin
Pen.Color := FCurves.Color[CurveIndex];
CurveArray := FCurves.PointArray(CurveIndex);
Polyline(CurveArray);
CurveArray := nil; //Параноик я, что поделать. На самом деле не нать
end;



 
Юрий Зотов ©   (2004-02-03 20:11) [12]

> Romkin © (03.02.04 19:07) [9]
> То же самое со string, только у них еще и счетчик копий есть

У динамических массивов он тоже есть. По крайней мере, в окне CPU он наблюдается по смещению -8. А по смещению -4 наблюдается текущая длина (кол-во элементов). Все как и в строках.

Вообще, вводя в язык динамические массивы, Borland поступила очень мудро - она использовала для работы с ними те же самые механизмы, что уже были отработаны на длинных строках.


 
Тимохов ©   (2004-02-03 20:16) [13]


> Вообще, вводя в язык динамические массивы, Borland поступила
> очень мудро - она использовала для работы с ними те же самые
> механизмы, что уже были отработаны на длинных строках.

Если позволите уточнение?
Механизмы то теже, за исключением того, что если после копирования строк путем присвоения одной пременной другой (s1 := s2) изменить строку-копию (s1), то это не скажется на строку-прототипе (s2). А в дин. массивах изменение массива-копии, будет синхронно влиять на массив-прототип.


 
jack128 ©   (2004-02-03 20:26) [14]


> А в дин. массивах изменение массива-копии, будет синхронно
> влиять на массив-прототип.
Пока я писал, ты уже отметил эту особенность :-)

Непонятно, что мешало борланду ввести у массивов такое же поведение, как и у строк


 
Тимохов ©   (2004-02-03 20:31) [15]


> Непонятно, что мешало борланду ввести у массивов такое же
> поведение, как и у строк

Имхо это сложно. Я бы сказал не возможно. Что ты будешь делить с объектами в записях, которые являются элементами массива?


 
jack128 ©   (2004-02-03 20:38) [16]


> Что ты будешь делить с объектами в записях, которые являются
> элементами массива?
А что ты делаешь сейчас при выполнении
arr2 := Copy(arr1, 0, Length(arr1)); ? ;-)


 
Юрий Зотов ©   (2004-02-03 20:46) [17]

> jack128 © (03.02.04 20:26) [14]

В строке четко известно, чем является каждый элемент - символом. А в динамическом массиве он может быть чем угодно (см. [15]). Например, еще одним динамическим массивом - и т.д. В итоге получается произвольно сложная структура и совершенно неясно, как такую ситуацию обрабатывать.


 
Тимохов ©   (2004-02-03 20:47) [18]

В данном случае дельфи оставляет на твою ответственность такое действо. Если облажаешься, сам дурак. Я (дельфи) тут ни при чем - я тебе не давала легкую возможность бездумно копировать массивы. Если ты такой умный, что можешь разобраться с таким случаем сам - флаг в руки, я не вредная.


 
Тимохов ©   (2004-02-03 20:48) [19]


> В итоге получается произвольно сложная структура и совершенно
> неясно, как такую ситуацию обрабатывать.

Рекурсивно!


 
Юрий Зотов ©   (2004-02-03 20:51) [20]

> Тимохов © (03.02.04 20:48) [19]

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


 
Тимохов ©   (2004-02-03 20:53) [21]


> Юрий Зотов © (03.02.04 20:51) [20]

Юрий!
Про рекурсию - была шутка. :)
Думаю, что посредством железных доводов, мы с Вами отстояли динамические массивы - они сделаны хорошо!


 
jack128 ©   (2004-02-03 20:55) [22]

To Юрий Зотов ©, Тимохов ©
В крайнем случае можно ограничется разрешением присваивания массивов из элемнтарных типов.


 
Romkin ©   (2004-02-03 20:57) [23]

Это как? Тут - присваивает, там - не присваивает? :))) Бедный программист


 
Тимохов ©   (2004-02-03 21:01) [24]


> jack128 © (03.02.04 20:55) [22]

Думаю вы все-таки не очень правы.
Поставте себя на место компилятора - ужас!


 
jack128 ©   (2004-02-03 21:02) [25]


> Это как? Тут - присваивает, там - не присваивает? :))) Бедный
> программист
нет, я имел в виду вообще запретить присваивание для дин массивов из неэлментарных типов. (например как запрещается создавать типизированные файлы из длинных строк)


 
Юрий Зотов ©   (2004-02-03 21:03) [26]

> Тимохов © (03.02.04 20:53) [21]

Думаю, таки да, действительно хорошо. А строки, IMHO, в Delphi вообще сделаны прекрасно. По крайней мере, намного эффективнее и удобнее, чем просто ASCIIZ.

> jack128 © (03.02.04 20:55) [22]

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


 
jack128 ©   (2004-02-03 21:05) [27]


> Тимохов © (03.02.04 21:01) [24]
??? Что сложного? Ограничения по определенных синтаксических конструкций изходя из типов переменных в языке уже есть (см типизированные файлы из длинных строк).
Вроде распарсерить тип элементов дин массива и определить входят ли туда объекты - не так сложно.


 
Тимохов ©   (2004-02-03 21:09) [28]


> jack128 © (03.02.04 21:05) [27]

А вот предствте каково бы жилось кодерам.

Создал массив записей из простых типов, все круто - копируется.
Потом при модернизации проги добавил в запись не простой тип (например, объект). Нажимаешь ф9, и кирдык. Лазь потом по коду, и вставляй копирование массивов. Оно вам надо?


 
Юрий Зотов ©   (2004-02-03 21:12) [29]

> jack128 © (03.02.04 21:05) [27]

> Вроде распарсерить тип элементов дин массива и определить
> входят ли туда объекты - не так сложно.

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

var
A: array of Integer;
...
SetLength(A, ...);
A[0] := Integer(TMyObject.Create);


 
jack128 ©   (2004-02-03 21:12) [30]

А вот предствте каково бы жилось кодерам.

Создал типизированный файл записей из простых типов, все круто - копируется.
Потом при модернизации проги добавил в запись не простой тип (например, объект). Нажимаешь ф9, и кирдык. Оно вам надо?

Заметь я заменил лишь пару слов ;-)


 
jack128 ©   (2004-02-03 21:16) [31]


> A[0] := Integer(TMyObject.Create);
Некорктный пример. При явном приведении типов программист берез всю ответственность на себя. При приваивании - компилятор должен обеспечить логичное поведение операндов(не уверен, что правильно использовал слово, поясню например при a := b логично, что содержимое b копируется в a. Если по техническим причинам это сложно реализовать, то крмпилятор должен сообщить об ошибке)


 
jack128 ©   (2004-02-03 21:18) [32]

небольшое исправление

> jack128 © (03.02.04 21:12) [30]
> А вот предствте каково бы жилось кодерам.
>
> Создал типизированный файл записей из простых типов, все
> круто - копируется.
> Потом при модернизации проги добавил в запись не простой
> тип (например, длинную строку). Нажимаешь ф9, и кирдык. Оно вам
> надо?
>


 
Юрий Зотов ©   (2004-02-03 21:20) [33]

> jack128 © (03.02.04 21:16) [31]

Хорошо, другой пример: array of Pointer. Этот Pointer может указывать вообще на что угодно, на любую структуру данных.


 
jack128 ©   (2004-02-03 21:24) [34]


> Юрий Зотов © (03.02.04 21:20) [33]
и что? при приваивании логично скопировать указатели. Это что, сложно реализовать? Непонял пример...


 
Юрий Зотов ©   (2004-02-03 22:12) [35]

> jack128 © (03.02.04 21:24) [34]

Указатель может прямо или косвенно указывать на данные с управляемым временем жизни. Как быть при копировании указателя - увеличивать счетчик ссылок на эти данные, или нет? И не менее (если не более) сложная задача - а как вообще распознать, что нетипизированный указатель ссылается на такие данные?


 
jack128 ©   (2004-02-03 22:32) [36]


> Юрий Зотов © (03.02.04 22:12) [35]


> Как быть при копировании указателя - увеличивать счетчик
> ссылок на эти данные, или нет?
А разве такое где то есть? Нет, конечно. Когда это копирование УКАЗАТЕЛЯ приводило к какому либо изменению самих данных?
s: string;
P1, P2: PString;
begin
P1 := @s;
P2 := P1; // Увеличение счетчика ссылок не происходит, так почему оно должно происходить при присваивании массивов array of PString??
end;


 
Kris   (2004-02-03 23:46) [37]

Удалено модератором
Примечание: IMHO, уважаемый - это оффтоп...


 
Юрий Зотов ©   (2004-02-04 00:19) [38]

> jack128 © (03.02.04 22:32) [36]

> А разве такое где то есть? Нет, конечно.

Еще как есть. Во-первых, длинные строки - это тоже самые настоящие типизированные указатели. Указывает такой адрес на запись со следующей структурой:

Смещение Содержимое
-8 Счетчик строк - ссылок на адрес со смещением 0
-4 Длина тела строки в байтах
0 Начало тела строки (кончается оно символом #0)

Для длинных строк характерен такой пример.

var
S1, S2: string;
begin
S1 := "Вася";

// Теперь S1 указывает на байт, содержащий букву "В".
// Находится этот байт в динамической памяти и
// по смещению -8 от него будет записано число 1.
S2 := S1;
// Копия тела строки не создается, а вместо этого происходит
// копирование адреса. Теперь S2 содержит в себе тот же адрес,
// что и S1, но по смещению -8 от него уже будет записано число 2

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

Совершенно то же самое и с динамическими массивами.
var
A1, A2: array of Integer;
begin
SetLength(A1, 10);

// Теперь A1 указывает на байт в динамической памяти, с
// которого начинается тело массива. По смещению -8 от этого
// байта будет записано число 1.
A2 := A1;
// Копия тела массива не создается, а вместо этого происходит
// копирование адреса. Теперь A2 содержит в себе тот же адрес,
// что и A1, но по смещению -8 от него уже будет записано число 2

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

Все это легко и наглядно проверяется в окне CPU. Да и в книгах есть (и даже частично описано в справке).

Так вот, для случая массива нетипизированных указателей
array of pointer
компилятор никак не может узнать, что же именно записывается в элемент массива при его присваивании. А вдруг туда пишется адрес строки? или еще одного динамического массива? Тогда он должен увеличивать счетчик ссылок в этой строке или массиве. А вдруг нет? Тогда не должен. Вот и получается, что компилятор не может распознать, что же ему делать. Соответственно, он и не сможет построить гарантированно правильный код.


 
Piter ©   (2004-02-04 00:56) [39]

>Вот это вообще новости! обязательно возьму на заметку, так все просто, что аж не по себе!

Вот вот! Я всегда говорил, что Сишники ругают Дельфи из-за того, что Дельфи то они и не знают!

P.S. А если честно - здесь столько нафлудили, что автор ветки, видимо, не вернется...


 
Kris   (2004-02-04 07:18) [40]


> Kris (03.02.04 23:46) [37]
> Удалено модератором
> Примечание: IMHO, уважаемый - это оффтоп...


Спасибо товаришь модератор! теперь вместо одного вопроса у меня появилось два. оказвыается я не знаю не ИМХО ни оффтоп. Спасибо еще раз помогли


 
Kris   (2004-02-04 07:27) [41]


> Piter © (04.02.04 00:56) [39]
> >Вот это вообще новости! обязательно возьму на заметку,
> так все просто, что аж не по себе!
>
> Вот вот! Я всегда говорил, что Сишники ругают Дельфи из-за
> того, что Дельфи то они и не знают!


ДА ничего подобного, сишники ругают, я вот например знаю си лучше чем делфи, но так уж получилось, в универе сначала преподавали Си а потом пас, причем если Си был дан в кол-ве 50%, то пас вообще дали в сравнительной характеристике - мол умные и сами разберетесь - это все было в филиале, а когда перевелся в базовый вуз, то там оказалось, что мы должны написать базу (курсовой), но предмета не будет, т.е. подразумевается, что ты уже все знаешь, так и началось знакомство с Дельфями. Ругать д никто не собирался, просто попробовал раз силу Сей потом ищешь то в чему привык, поэтому повторюсь:


> "Язык формирует наш способ мышления и определяет, о чем
> мы можем мыслить."
> - Б.Л.
> Ворф


Я лично прихожу на этот форум узнать немного больше чем знаю щас, и не обязательно по дельфям.


> P.S. А если честно - здесь столько нафлудили, что автор
> ветки, видимо, не вернется...


Нет, нет! я тут бываю регулярно, все мои ветки в закладках, мне очень интересно, что тут такие дебаты! Кстати эта ветка даже в рассылку попала :)


 
jack128 ©   (2004-02-04 11:30) [42]


> Во-первых, длинные строки - это тоже самые настоящие типизированные
> указатели.
Юрий, все таки это, ИМХО, не документированные, хотя и общеизвестные данные. Нельзя на их основе проводить аналогии на обычные указатели. Тоже самое относится и к дин массивам. И к строкам, и к дин. массивам нужно относится как к _недокументированной_ структуре данных, и уж закладаваться на то, что строка - именно указатель никак не стоит..

Еще раз:

> P2 := P1; // Увеличение счетчика ссылок не происходит, так
> почему оно должно происходить при присваивании массивов
>


 
Тимохов ©   (2004-02-04 11:45) [43]


> все таки это, ИМХО, не документированные, хотя и общеизвестные
> данные

Зря вы так думаете, это документировно - см. хелп object pascal reference\memort managment.


 
Юрий Зотов ©   (2004-02-04 12:31) [44]

> jack128 © (04.02.04 11:30) [42]

> все таки это, ИМХО, не документированные

Только что посмотрел - все это полностью есть в справке D7.

> P2 := P1; // Увеличение счетчика ссылок не происходит, так
> почему оно должно происходить при присваивании массивов

Потому что, если при присвоении массива не увеличить счетчик ссылок на него, то программа практически наверняка нарвется на Access Violation. Абсолютно то же самое и со строкой, да и вообще с любыми данными с управляемым временем жизни.


 
jack128 ©   (2004-02-04 12:34) [45]


> см. хелп object pascal reference\memort managment.
Да действительно..Я не прав.

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


 
Тимохов ©   (2004-02-04 12:36) [46]


> jack128 © (04.02.04 12:34) [45]

Вы, уважаемый, на логику строк не наезжайте - ничего лучше дельфовых строк нет :)))

Кстати, каковы Ваши предложнения боланду - что он должен переделать в следующей версии?


 
jack128 ©   (2004-02-04 12:38) [47]


> Потому что, если при присвоении массива не увеличить счетчик
> ссылок на него, то программа практически наверняка нарвется
> на Access Violation. Абсолютно то же самое и со строкой,
> да и вообще с любыми данными с управляемым временем жизни.
Нет, я не так выразился. Имелось в виду, почему при привоении массивов array of PString? должны увеличиваться счетчики ссылок string"ов?
Вы ведь этого хотите?

> Хорошо, другой пример: array of Pointer. Этот Pointer может
> указывать вообще на что угодно, на любую структуру данных.


> Указатель может прямо или косвенно указывать на данные с
> управляемым временем жизни. Как быть при копировании указателя
> - увеличивать счетчик ссылок на эти данные, или нет? И не
> менее (если не более) сложная задача - а как вообще распознать,
> что нетипизированный указатель ссылается на такие данные


 
jack128 ©   (2004-02-04 12:49) [48]


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

> Кстати, каковы Ваши предложнения боланду - что он должен
> переделать в следующей версии?
по поводу чего? Строк? Ничего не должен, все и так хорошо.
По поводу дин массивов - я высказался - чтобы при приваивании массивов и последующим изменении одного из них - происходило копирование одного из этих массивов и изменение происходило уже над копией. (как в строках)

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


 
Piter ©   (2004-02-04 13:56) [49]

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

Так в том то и дело, что Сишники часто не понимают, что Дельфи НИЧЕМ не уступает Си по силе :)

Есть пара спорных моментов вроде:
- наследование от более, чем одного класса - преимущество спорное, если надо - в Дельфи есть интерфейсы.
- Перегрузка операторов - тоже спорно. Ничего такого, чтобы вместо A+B использовать Add(A,B)

Я лично прихожу на этот форум узнать немного больше чем знаю щас, и не обязательно по дельфям

Вот честное слово - тебе бы книжечку по Delphi, по ООП желательно.
Возьми обязательно книгу Тейксера и Пачеко "Руководство разработчика". Вот когда ты прочитаешь там половину, когда вникнешь в принципы VCL, когда ты узнаешь что такое динамические массивы, как это просто и здорово, когда ты узнаешь как устроен string - ты просто протащишься по полной. Дельфи тебе покажется раем по сравнению с Си, никаких утечек памяти, никакой мелкой работы по бескончному выделению, освобождения памяти. Ты узнаешь что такое типы с "уборкой мусора". Вроде все элементарно, но это так здорово.


 
alex_*** ©   (2004-02-04 14:09) [50]


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

Хорошо в стране советской жить.... прямо как в сказке ))


 
Юрий Зотов ©   (2004-02-04 14:21) [51]

> jack128 © (04.02.04 12:49) [48]

> чтобы при приваивании массивов и последующим изменении одного
> из них - происходило копирование одного из этих массивов и
> изменение происходило уже над копией. (как в строках)

Пусть элемент массива ссылается на объект. Присвоили. Что копировать - ссылку или сам объект? Если первое - опасность AV, если второе - опасность утечки памяти.

Пусть элемент массива ссылается на строку или динамический массив. Присвоили. Что делать со счетчиком ссылок? Если увеличивать, то когда и как потом уменьшать (иначе - опасность утечки памяти)? Если не увеличивать - опасность AV.

И как вообще распознать, что именно загоняется в элемент массива array of pointer?

====================================

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

А уж потом отвечайте.


 
jack128 ©   (2004-02-04 15:01) [52]


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

в идеале
arr2 := arr1;
эквивалентно
setlength(arr2, Length(arr1);
for i := 0 to Length(Arr1) do
arr2[i] := arr[1];
Это достаточно ясно? Если элемент массива содержит еще дин массив, то это разрулевается рекурсией.


 
Тимохов ©   (2004-02-04 15:03) [53]

Т.е. ваш идеал состоит в том, что arr2 := arr1 вообще работать не должно? :))))


 
jack128 ©   (2004-02-04 15:09) [54]


> Т.е. ваш идеал состоит в том, что arr2 := arr1 вообще работать
> не должно? :))))
если, насчет опечаток, то я думаю, в отличии от меня борландовские программисты их недопустят.
Если, что иное, то я не понял..

P.S. Пора закруглятся, я думаю..


 
Юрий Зотов ©   (2004-02-04 15:30) [55]

> jack128 © (04.02.04 15:01) [52]

ОК. Теперь добавляю к Вашему коду РЕАЛЬНОЕ объявление массивов и снова прошу ответить на те же самые вопросы.

var
Arr1, Arr2: array of pointer ; // !!!!!!!!!
begin
...
Arr2 := Arr1;

Согласно Вашему предложению, при присвоении компилятор должен построить следующий код:

SetLength(Arr2, Length(Arr1);
for i := 0 to Length(Arr1) - 1 do
begin
Arr2[i] := Arr1[i];
... // 1. Нужны ли здесь какие-то дополнительные действия?
... // 2. Если да, то какие именно?

end

Вот на эти 2 конкретных вопроса (выделены жирнвм и подчеркнуты) я и прошу Вас так же конкретно ответить. Поставьте себя на место разработчика компилятора и скажите - как именно в данном случае Вы будете реализовывать Ваше предложение.

=============================================================

Кстати, раз уж Вы хотите, чтобы массивы вели себя, как строки, то знайте, что при присвоении S2 := S1 как раз никакого копирования тела строки не происходит, а копируется только ссылка . То есть, при присвоении строк никакого кода, аналогичного тому, что Вы написали тоже НЕ выполняется.

О чем было ПРЯМО написано в [38] - в связи с чем очень прошу Вас читать внимательнее и вдумчивее.


 
jack128 ©   (2004-02-04 15:41) [56]


> при присвоении S2 := S1 как раз никакого копирования тела
> строки не происходит, а копируется только ссылка.
да согласен, я был не внимателен. :-(
Скажем так
arr2 := arr1; - увеличивается счетчик ссылок

Arr2[12] := <SameValue>; - хотелось бы, что бы это вызывало следующий код

SetLength(Arr2, Length(Arr1));
for i := 0 to Length(Arr1) - 1 do
Arr2[i] := Arr1[i];
Arr[2] := <SameValue>


> var
> Arr1, Arr2: array of pointer; // !!!!!!!!!
> begin
> ...
> Arr2 := Arr1;
>
> Согласно Вашему предложению, при присвоении компилятор должен
> построить следующий код:
>
> SetLength(Arr2, Length(Arr1);
> for i := 0 to Length(Arr1) - 1 do
> begin
> Arr2[i] := Arr1[i];
> ... // 1. Нужны ли здесь какие-то дополнительные действия?
> ... // 2. Если да, то какие именно?
Нет, зачем? Снова сошлюсь например с PString. Разве при PStringVariable2 := PStringVariable1 присходят какие то дополнительны действия? Это в случае типизированных указателей, для нетипизированных же, даже если я что нить захотел бы сделать - не смог бы. Но я этого и не хочу!!!

> end


 
Тимохов ©   (2004-02-04 15:53) [57]


> jack128 © (04.02.04 15:41) [56]

Не упорствуйте в ереси :)))))
Я по поводу

SetLength(Arr2, Length(Arr1));
for i := 0 to Length(Arr1) - 1 do
Arr2[i] := Arr1[i];
Arr[2] := <SameValue>

А если в Arr2 лежат объекты.
И происходит Arr2[i].SomePropery := 0;

Что тогда?

Думаю, действительно, пора закругляться?


 
jack128 ©   (2004-02-04 15:58) [58]

>>Не упорствуйте в ереси :)))))
Я атеист ;-)

> А если в Arr2 лежат объекты.
> И происходит Arr2[i].SomePropery := 0;

А что происходит при
a, b : TMyObject;
begin

b := a;
b.SameProperty := 0;
// почему вы отказываете в таком поведении элементам массива?
end;

> Думаю, действительно, пора закругляться?
Пора-а-а удира-а-ать. Пора, брат, пора!!!(с)


 
Lucky[ELF] ©   (2004-02-04 19:24) [59]


> Piter © (04.02.04 13:56) [49]
> Ругать д никто не собирался, просто попробовал раз силу
> Сей
>
> Так в том то и дело, что Сишники часто не понимают, что
> Дельфи НИЧЕМ не уступает Си по силе :)


Ну вопервых вы сами знаете Си?
Я не буду утвержадть чем уступает Делфи потому как я во многом этого не знаю, но если хотите мой друг имеет международный диплом специалиста по сям (помоему что-то типа IEEE - точно не помню) обосновать это запросто, но дело не в этом, мне это не нужно, а вам? давайте не будем спорить на эту тему!

И еще хочу заметить, что делфи со своей мощью еще очень молод, а си базовый язык, так что во многом МОЖЕТ БЫТЬ некоторые вещи взяты из других языков, кроме этого, если взять например первый делфи, то я думаю он не будет так крут.


> Есть пара спорных моментов вроде:
> - наследование от более, чем одного класса - преимущество
> спорное, если надо - в Дельфи есть интерфейсы.
> - Перегрузка операторов - тоже спорно. Ничего такого, чтобы
> вместо A+B использовать Add(A,B)


По поводу наследования от одного класса я ничего не скажу, ну незнаю я преимущество это или нет?

А по поводу второго, хотелось бы увидеть как выглядит этот самый Add т.е. его внутринности, при условии, что A,B,C - объекты одного типа?
я так понимаю что вызов выглядит как C.Add?
А если надо A+B+C+D+E+F....

а что вы будете делать на *nix? там есть делфи?
и еще сила сей подтверждается в мировом масштабе - мое слово тут ничего не значит, поскольку есть гораздо больше известных людей которые могут точно сказать почему си, (непонятен еще и тот вопрос почему все большие комерчиские вещи пишутся на Сях - в особенности игры - не встречал ни одной серьезной не на сях, драйвера, утилиты и ос, про ОС слышал, правда это или нет, но вроде бы win3.1 был на пасе), я за такое не берусь. во многом мой выбор пал из-зи того, что Си располагает к приятному написанию, т.е.

int x=1;
float a,b,c;
a=b=c=0;
..
max = ((value1 > value2) ? value1 : value2);
{
int t=x;
for (int w=0; w<t; w++)
}


Все эти приятное мелочи и другие тоже заставляют меня делать свой выбор и это си, но это вовсе не значит, что я не пишу не Дельфях - пишу в основном базы, в остальном VC++ or Builder С++ - как раз и альтернатива Дельфям - все теже компаненты, так что жить можно :)


 
Тимохов ©   (2004-02-04 19:28) [60]


> Lucky[ELF] © (04.02.04 19:24) [59]

Думаю это уже совсем флуд. Но все же скажу.
Си признан в мировом масштабе, т.к. в мировом масштабе М$ всех имеет - что она зохочет то и будет. К достинствам и недостаткам дельфи это отношения не имеет, имхо.


 
jack128 ©   (2004-02-04 19:35) [61]


> но если хотите мой друг имеет международный диплом специалиста
> по сям (помоему что-то типа IEEE - точно не помню) обосновать
> это запросто,
Мда? А не находишь противоречия в том, что человек, знающий С, критикует Delphi ?


 
Юрий Зотов ©   (2004-02-04 20:03) [62]

Мне другое понравилось:
"давайте не будем спорить на эту тему"

После чего последовала еще сотня строк в доказательство того, что круче С только яйца.

:о)


 
Lucky[ELF] ©   (2004-02-04 21:03) [63]

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


> Тимохов © (04.02.04 19:28) [60]
>
> > Lucky[ELF] © (04.02.04 19:24) [59]
>
> Думаю это уже совсем флуд. Но все же скажу.
> Си признан в мировом масштабе, т.к. в мировом масштабе М$
> всех имеет - что она зохочет то и будет. К достинствам и
> недостаткам дельфи это отношения не имеет, имхо.


Если всемирная организация по стандартизации IEEE, в которой есть стандарт Сей и не какой мелкософт тут ни причем.

А линух он по вашему как написан, а юникс, а нетварь - на чем они писались, почему под линухом пишут на сях?
но совршенно верно к достоинствам и недостаткам д это отношения не имеет.


> jack128 © (04.02.04 19:35) [61]
>
> > но если хотите мой друг имеет международный диплом специалиста
>
> > по сям (помоему что-то типа IEEE - точно не помню) обосновать
>
> > это запросто,
> Мда? А не находишь противоречия в том, что человек, знающий
> С, критикует Delphi ?


Никто не говорил о критике! просто я сказал, что я не знаю особых приимуществ - он мне просто больше нравиться (такое может быть?), а мой друг просто может высказать все точно.


> Юрий Зотов © (04.02.04 20:03) [62]
> Мне другое понравилось:
> "давайте не будем спорить на эту тему"
>
> После чего последовала еще сотня строк в доказательство
> того, что круче С только яйца.
>
> :о)

Да все заканчиваем. я вообще считаю, что язык надо выбирать для каждой задачи отдельно, пример тому пролог, после паса/сей его вообще не понять - один сплошной переврнутый IF


Ребяты на самом деле давайте прекратим эту словесную дуэль, потому как мастерство не зависит от "крутизны" языка, и не дает особых приимуществ если знаешь язык еле-еле.
Пусть каждый выбирает себе язык сам! я лично как сказал ранее делаю это исходя из задачи.


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

С уважением Lucky[ELF]


 
Юрий Зотов ©   (2004-02-04 21:09) [64]

Второй этап. Изучение языков.
Третий еще не пришел. Их понимание.
Когда придет - станет без разницы.


 
Lucky[ELF] ©   (2004-02-04 21:18) [65]

Да возможно так и есть!
а первый какой?

ЗюЫю помоему разговор пошел не в тему :)


 
Юрий Зотов ©   (2004-02-04 21:26) [66]

> Lucky[ELF] © (04.02.04 21:18) [65]

Первый - это "Hello, world!" и дикая радость вперемешку с гордостью. Оттого, что работает и даже почти понятно, как.


 
Lucky[ELF] ©   (2004-02-04 21:39) [67]

А понятно! но у меня это было 1 и 1/2, потому что у меня сначала был BASIC на Z80, а ужо потом Hello, world!
А не понятного пока много! :-)


 
Юрий Зотов ©   (2004-02-04 21:48) [68]

> Lucky[ELF] © (04.02.04 21:39) [67]

> А не понятного пока много!

Значит, не в ту сторону Вы пошли - не вглубь, а вширь. Не языки Вам сейчас надо осваивать (языки - это вообще ерунда), а типы данных и их машинное представление, стандартные алгоритмы, работу с памятью, устройство системы и пр. На любом языке, без разницы на каком.

А когда Вы эти вещи освоите, то сами увидите, что Вам уже стало без разницы, на каком языке писать. Понимание придет.


 
Lucky[ELF] ©   (2004-02-04 21:56) [69]


> Юрий Зотов © (04.02.04 21:48) [68]
> > Lucky[ELF] © (04.02.04 21:39) [67]
>
> > А не понятного пока много!
>
> Значит, не в ту сторону Вы пошли - не вглубь, а вширь. Не
> языки Вам сейчас надо осваивать (языки - это вообще ерунда),
> а типы данных и их машинное представление, стандартные алгоритмы,
> работу с памятью, устройство системы и пр. На любом языке,
> без разницы на каком.
>
> А когда Вы эти вещи освоите, то сами увидите, что Вам уже
> стало без разницы, на каком языке писать. Понимание придет.


Да наверное, но мне во многом нравиться именно как пишется, а не то какие возможности он дает - возможно это плохо.

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


 
Юрий Зотов ©   (2004-02-04 22:07) [70]

> Lucky[ELF] © (04.02.04 21:56) [69]

> Ну с другой стороны для пролога например вовсе не важно не
> память ни система, также и для перла

Вы в этом уверены?


 
Lucky[ELF] ©   (2004-02-04 22:36) [71]

"Язык формирует наш способ мышления и определяет, о чем мы можем мыслить.
- Б.Л. Ворф"


> Юрий Зотов © (04.02.04 22:07) [70]
> > Lucky[ELF] © (04.02.04 21:56) [69]
>
> > Ну с другой стороны для пролога например вовсе не важно
> не
> > память ни система, также и для перла
>
> Вы в этом уверены?


А у вас другая информация на эту тему?
т.е. если важна система, то скрипт перла не будет или будет не правильно работать на другой ОС, так?

А с прологом вы сталкивались? где важно знать машинное представление типов данных и устройство системы?


 
Lucky[ELF] ©   (2004-02-04 22:42) [72]


> А с прологом вы сталкивались? где важно знать машинное представление
> типов данных и устройство системы?


имеется в виду где в прологе.


 
Lucky[ELF] ©   (2004-02-07 21:05) [73]


> Юрий Зотов © (04.02.04 21:48) [68]
> > Lucky[ELF] © (04.02.04 21:39) [67]
>
> > А не понятного пока много!
>
> Значит, не в ту сторону Вы пошли - не вглубь, а вширь. Не
> языки Вам сейчас надо осваивать (языки - это вообще ерунда),
> а типы данных и их машинное представление, стандартные алгоритмы,
> работу с памятью, устройство системы и пр. На любом языке,
> без разницы на каком.
>
> А когда Вы эти вещи освоите, то сами увидите, что Вам уже
> стало без разницы, на каком языке писать. Понимание придет.


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

про работу с памятью мне вообще непонятно, потому как она во всех языках реализована по разному, так что тут как раз надо изучать эту вещь в конкретном языке, а на абстрактных вещах это врядли можно понять.

по поводу машинного представления - я всегда считал что машиное представлени всегда одинаковое 10101000100 ... или я не понял вас - тогда поясните

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

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

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

Вот такие пирожки с котятами!

С уважением Lucky[ELF].


 
VMcL ©   (2004-02-08 00:29) [74]

>>Lucky[ELF] © (07.02.04 21:05) [73]
>а почему, да потому, что в этих языках отсутстуют инструменты для выполнения такой задачи, так что получается язык очень важен и вовсе не ерунда

Ты здесь говоришь не о языке, а о среде. Драйвер под Win32 можно написать (только) на C и на Asm? Неверно, на MSVC и на MASM. А это уже не языки в чистом виде, а их модификации от MS.


 
Lucky[ELF] ©   (2004-02-08 11:35) [75]


> Ты здесь говоришь не о языке, а о среде. Драйвер под Win32
> можно написать (только) на C и на Asm? Неверно, на MSVC
> и на MASM. А это уже не языки в чистом виде, а их модификации
> от MS.


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

Модификации, но опять же все того же языка, (Си, Пас, асм просто приведены в качестве примера) ведь все равно в любой модификации возможности языка сохряняются.


 
Anatoly Podgoretsky ©   (2004-02-08 12:23) [76]

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


 
Lucky[ELF] ©   (2004-02-08 12:41) [77]


> Anatoly Podgoretsky © (08.02.04 12:23) [76]
> Начать лучше с русского языка, потом можно браться и за
> иностранные

Да? ну лано возьму на заметку, но ошибок не делает только тот кто вообще ничего не делает.



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

Текущий архив: 2004.02.17;
Скачать: CL | DM;

Наверх




Память: 0.76 MB
Время: 0.032 c
1-53546
zamkom
2004-02-09 11:16
2004.02.17
MessageDlg


1-53453
JediMaster
2004-02-06 13:00
2004.02.17
Простые числа


14-53703
Ig
2004-01-29 23:13
2004.02.17
Выключение компьтера по сети


7-53786
vbazik
2003-12-01 20:05
2004.02.17
Возможно ли в Delphi писать приложения для КПК под WinCE


1-53545
Алхимик
2004-02-05 13:07
2004.02.17
TOpenDialog & Dll