169 похожих чатов

Скажите, можно ли как-то "переместить" динамический массив из одной переменной

в другую?
Скажем, переместить из TList<> в TArray<>. Именно переместить, а не скопировать.
Если использовать метод ToArray, будет копия. Если использовать свойство List, будет просто присвоение, и при освобождении TList<> массив будет тоже уничтожен.

37 ответов

93 просмотра

Правильно ли понимаю задачу: извлечь указатель массива из приватного поля TList<>.FItems и сбросить указатель в этом же поле на nil?

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Alexander Somov
Правильно ли понимаю задачу: извлечь указатель мас...

Ну по сути да. Только из этого указателя ещё и массив сделать.

Eugene Krasnikov (ᴊɪɴ x)
Ну по сути да. Только из этого указателя ещё и мас...

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

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Alexander Somov
Не совсем ясно, что понимается под "массив сделать...

Сам по себе указатель меня не интересует. Мне нужен массив. Если можно превратить указатель в массив всякими хаками, я не против. Потому что мне не указатель нужен, а массив. Чтобы он потом сам уничтожился при выходе из скоупа и пр. дела

Alexander Somov
Не совсем ясно, что понимается под "массив сделать...

Если есть переменная (по сути это именованный указатель на область памяти, т.к. по сути содержит адрес памяти и тип данных в ней). Т.е. если переменной одного типа присвоить один и тот же адрес, то они будут отображать одни и те же данные. В TList<>.FItems внутри и так массив, по сути такая же структура, что и в TArray<>. Собственно не ясно для чего делать это перемещение указателей? Если вопрос в оптимизации, то в TList<> всё сделано достаточно эффективно, чтобы минимизировать все эти операции с перемещениями блоков памяти. PS: Есть подозрение, что что-то делаете не так в логике работы с данными :(

uses Generics.Collections; type PDynArrayRec = ^TDynArrayRec; TDynArrayRec = packed record {$IFDEF CPU64BITS} _Padding: Integer; // Make 16 byte align for payload.. {$ENDIF} RefCnt: Integer; Length: NativeInt; end; var L: TList<Integer>; A: TArray<Integer>; begin L := TList<Integer>.Create; for var I := 0 to 9 do L.Add(I); PPointer(@A)^ := PPointer(L.PList)^; PDynArrayRec(PByte(A) - SizeOf(TDynArrayRec))^.Length := L.Count; PPointer(NativeInt(L.PList) + SizeOf(Pointer))^ := 0; L.Free; for var I := 0 to Length(A) - 1 do Writeln(A[I]); end.

Jack128
Зачем плохому учишь??

Ну если ему пофиг, лишь бы результат - чо бы и нет?

Александр (Rouse_) Багель
uses Generics.Collections; type PDynArrayRec ...

Чтобы такое оправдать надо гигабайт в этот tlist положить...

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Alexander Somov
Если есть переменная (по сути это именованный указ...

Я генерирую список. Мне удобнее работать через TList<String>, через через TArray<String>. Результат хочу закинуть в TStringList.

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Eugene Krasnikov (ᴊɪɴ x)
Я генерирую список. Мне удобнее работать через TLi...

Хотя тут, наверное, и через PList можно забубунить :)

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Eugene Krasnikov (ᴊɪɴ x)
Гигабайт вполне возможен.

Уверен что у тебя столько свободных страниц неразрывно будет доступно?

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Александр (Rouse_) Багель
Уверен что у тебя столько свободных страниц неразр...

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

Eugene Krasnikov (ᴊɪɴ x)
Гигабайт вполне возможен.

Гигабайт указателей на строки? Или вместе с содержимым гигабайт?

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Michael Longneck
Гигабайт указателей на строки? Или вместе с содерж...

100 млн строк до 20 символов, например. Строки копируются из других мест, так что по сути указатель+счётчик+т.п. хрень.

Eugene Krasnikov (ᴊɪɴ x)
100 млн строк до 20 символов, например. Строки коп...

Тогда тут string не нужен, до 20 символов. Быстрее будет использовать массив, причем фиксированной длины

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Michael Longneck
Тогда тут string не нужен, до 20 символов. Быстрее...

Это в среднем до 20, по факту может быть почти любая длина.

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Александр (Rouse_) Багель
uses Generics.Collections; type PDynArrayRec ...

Как хак норм, но проще сделать как сделал, чем вот это всё.

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Роман Лях (rgreat)
Покажи :)

Capacity := 0; Idx := 0; // adding if Idx <= Capacity then begin if Capacity < 16 then Capacity := 16 else if Capacity < 1024 then Capacity := Capacity * 2 else Capacity := Capacity * 3 div 2; SetLength(Arr, Capacity); end; Arr[Idx] := Value; Inc(Idx); В таком духе.

Eugene Krasnikov (ᴊɪɴ x)
Capacity := 0; Idx := 0; // adding if Idx <= Capac...

А причем тут дублирование массива?

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Eugene Krasnikov (ᴊɪɴ x)
Capacity := 0; Idx := 0; // adding if Idx <= Capac...

Что происходит при выполнении SetLength с данными в массиве ясно?

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Alexander Somov
Что происходит при выполнении SetLength с данными ...

Копируются в новый массив (если места нет для расширения). Остальные не определены (если не managed type).

Alexander Somov
Что происходит при выполнении SetLength с данными ...

Ну от "суперскорости" он явно отказался.

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Eugene Krasnikov (ᴊɪɴ x)
Ок. Ваше предложение.

Без понятия. Я не в теме задачи.

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Eugene Krasnikov (ᴊɪɴ x)
Capacity := 0; Idx := 0; // adding if Idx <= Capac...

Кстати, интересно сравнить скорость такого похода и TList :)

Eugene Krasnikov (ᴊɪɴ x)
Кстати, интересно сравнить скорость такого похода ...

Самая быстрая скорость - это работать с первоисточником. Без копирования.

Eugene Krasnikov (ᴊɪɴ x)
Копируются в новый массив (если места нет для расш...

Так исходно, в "постановки задачи" была речь о требовании избежать копирование данных. В общем, варианты решения достаточно подробно уже обсудили. Какие есть дополнительные требования и ограничения, да и информация о виде поступающих данных - вам лучше известны, т.ч. и карты вам в руки )) PS: Магии не бывает, только то, что мы ещё не понимаем )) Любые обёртки имеют своей целью не получить максимальную скорость и эффективность, а упрощают выполнение типовых задач (тот же TList будет работать аналогично, при ручной корректировке его Capacity).

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Роман Лях (rgreat)
Самая быстрая скорость - это работать с первоисточ...

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

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса
Alexander Somov
Так исходно, в "постановки задачи" была речь о тре...

Ну в TList там куча какой-то оптимизации, Internal***-функции и пр. А без копирования при заполнении массива как, если я не знаю финальный размер. Поэтому только так.

Eugene Krasnikov (ᴊɪɴ x)
Ну в TList там куча какой-то оптимизации, Internal...

ну например цепочка блоков с данными. если нужен o(1) доступ - то повыерх них массив указателей. Так Delphi RTL работает с Windows, есть там в ней что-то типа MakeAtom или makecallback, которая исторически течет памятью в серверах при неудачных добавлениях/отменах этих элементов. вообще, для дельфи полно разных контейнеров/коллекций с разными свойствами, в том же JCL, или на Торри порыться Другой вопрос ЧТО именно надо, какие виды работы насколько часто, какой размер данных, какая цена копирования и т.д. Может быть банальный односторонний связанный список будет быстрее всего 😊

Eugene Krasnikov (ᴊɪɴ x)
Capacity := 0; Idx := 0; // adding if Idx <= Capac...

исправление капасити, если индекс МЕНЬШЕ или равен капасити? не БОЛЬШЕ или равен?

Eugene-Krasnikov (ᴊɪɴ x) Автор вопроса

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта