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

Вниз

Динамическое создание строк   Найти похожие ветки 

 
Skier   (2002-06-26 13:18) [0]

Господа, мне нужно динамически создавать строки
(не PChar, а именно String(!) )

Я делаю что-то вроде этого :

.......................
type
PString = ^String;
var
AStr := AllocMem(4);
AStr^ := "hello, world !"
FreeMem(AStr, 4);
.......................

Вроде бы всё работает, но что-то меня
терзают смутные сомненния : не происходит ли memory leak ?
И вообще как это всё лучше всего делать ?


 
Kaban   (2002-06-26 13:26) [1]

че-то я не вижу где тут "динамически создаются строки"
и что вы вообще под этим подразумеваете


 
Anatoly Podgoretsky   (2002-06-26 13:27) [2]

Зачем такое извращение, работа со строками и так происходит динамически и автоматически.


 
Игорь Шевченко   (2002-06-26 13:29) [3]

А зачем? Строка же так создается динамически и, по сути, является указателем


 
Skier   (2002-06-26 13:29) [4]

> Kaban

Ну да... не строка создаётся, а указатель на неё родимую.
Но всё равно вроде работает, а вроде бы что-то тут не так...


 
panov   (2002-06-26 13:31) [5]

str := "hello, world !";
...
str := ""; //память освобождена


 
Skier   (2002-06-26 13:33) [6]

> Игорь Шевченко
> Anatoly Podgoretsky

Мне нужно программно создать указатель на строку и работать
с ней, а потом этот указатель прибить.
Но меня интересует убъётся ли строка hello, world ! ?
(в моём случае) станет ли кол-во сслылок на неё = 0, чтобы
Delphi снесла её из памяти ??


 
Kaban   (2002-06-26 13:34) [7]

По моему это уж лишнее
str := ""; //память освобождена


 
Kaban   (2002-06-26 13:36) [8]

Бред


 
panov   (2002-06-26 13:36) [9]

>Kaban © (26.06.02 13:34)
По моему это уж лишнее
В общем случае - нет. -)
Например, для глобальных переменных...


 
panov   (2002-06-26 13:37) [10]

>Skier © (26.06.02 13:18)
FreeMem освобождает память. В чем проблема-то?


 
Игорь Шевченко   (2002-06-26 13:42) [11]

Skier © (26.06.02 13:33)

Не можете привести пример, а то непонятно...

По-моему, проще не мучиться со строками, а выделить память под текст, иметь на него указатель типа PChar...


 
Skier   (2002-06-26 13:44) [12]

> panov

Проблема в следующем : будет ли освобождаться
память выделенная Delphi под "hello, world !" ?
Меня это очень интересует.


 
:smile:   (2002-06-26 13:49) [13]

Не будет. Освободится только 4 байта указателя.


 
Skier   (2002-06-26 13:49) [14]

> Игорь Шевченко
Код я весь привёл.
Мне нужен именно String (см. Вопрос)

будет ли освобождаться память выделенная Delphi под "hello, world !" ?
Т.е. будет ли обнуляться счётчик ссылок на "hello, world !" ?


 
Kaban   (2002-06-26 13:51) [15]

Приведенный вами код значительно упроститься, если вы будите использовать переменную типа string


 
Skier   (2002-06-26 13:52) [16]

> :smile:
"Не будет" - это не ответ.
Нужны доказательства !


 
Skier   (2002-06-26 13:55) [17]

> Kaban
ОГРОМНОЕ СПАСИБО !
Я никак не мог догадаться :)


 
Kaban   (2002-06-26 14:00) [18]

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


 
panov   (2002-06-26 14:01) [19]

будет ли освобождаться память выделенная Delphi под "hello, world !" ?

Да. Странно было бы, если бы память не освобождалась.
String/AnsiString стандартный тип в паскале и Delphi прекрасно умеет с ним работать.

При выполнении оператора присваивания
AStr^ := "hello, world !";
память динамически перераспределяется и
FreeMem(AStr) будет освобождать не 4 байта памяти, а именно столько, сколько выделено под "hello, world !".

Т.е. будет ли обнуляться счётчик ссылок на "hello, world !" ?
Непонятно, о чем речь.


 
Viewer   (2002-06-26 14:02) [20]

Ну так и докажи себе сам.
В цикле набери длину строки на 1Мег
s := s + "1234567890";
Посмотри на MemAvailable
Затем s := "";
И опять посмотри.


 
:smile:   (2002-06-26 14:03) [21]

>Skier © (26.06.02 13:52)
>"Не будет" - это не ответ.
"Не будет" - это как раз ответ. На вопрос "будет ли..."

Просьбы о доказательствах я не видел.
Вообще-то это очевидная вещь.


 
VDen   (2002-06-26 14:04) [22]

Per rectum ad astera :))


 
Skier   (2002-06-26 14:05) [23]

> Kaban
Извини я если обидел (не хотел)
Просто разумная причина довольно глобальна, вот
я и эксперементирую по мелочам.
И я хочу использовать именно приведённый мной код.
Вот только у меня возникли вопросы...


 
Skier   (2002-06-26 14:10) [24]

> panov
"Непонятно, о чем речь"
Речь о том что "в строке" (когда память под
неё выделяет Delphi) храниться её длина и количество ссылок
на неё, так вот если на строку больше никто не ссылается то она
сносится из памяти. Отсюда и мой вопрос.
И мне очень бы хотелось получить на него доказательный ответ.
Ну очень нужно !


 
Skier   (2002-06-26 14:12) [25]

> VDen
Да, да именно к звёздам !
А конкретно что-нибудь можешь сообщить ?


 
panov   (2002-06-26 14:12) [26]

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

Почему это она сносится из памяти?

Раз ты динамически создаешь переменную типа String, то пока ты ее принудительно не освободишь FreeMem, никуда память не освободится, и ссылки тут ни при чем.


 
Kaban   (2002-06-26 14:14) [27]

>Речь о том что "в строке" (когда память под
>неё выделяет Delphi) храниться её длина и количество ссылок
>на неё, так вот если на строку больше никто не ссылается то она
>сносится из памяти.
Че то я в этом сильно сомневаюсь


 
VDen   (2002-06-26 14:15) [28]

2Skier © (26.06.02 14:12)
Вообще-то вы меня неправильно поняли. "Per rectum" - термин медицинский, означает "через задний проход". Можно сделать проще...


 
Skier   (2002-06-26 14:16) [29]

> panov
"ссылки тут ни при чем"
Как ты не прав !
Я динамически создаю указатель на строку и потом
"говорю" Delphi разместить там ссылку на "hello, world !".

А FreeMem освобождает только указатель. или нет ?


 
Anatoly Podgoretsky   (2002-06-26 14:19) [30]

panov © (26.06.02 14:01)
Шире, ключевое слово, часть языка, в отличии от других типов


 
McSimm   (2002-06-26 14:20) [31]

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

Освобождения памяти от строки не произойдет.
Какие доказательства тут можно привести? Могу предложить посмотреть ассемблерный код, сгенерированный компилятором.

>если на строку больше никто не ссылается
Этот аргумент здесь не подходит. "AStr^ := " не увеличивает ref.count строки. И тут все зависит от того способа каким это строка создана.


 
Skier   (2002-06-26 14:27) [32]

> McSimm
Мне кажеться, что AStr^ := "hello, world !"
создаёт строку "hello, world !" в памяти, вот
если написать так :

AStr^ := "hello, world !";
а потом
AStr^ := "";
(далее всё по тексту)

То в этом случае memory leak не будет точно или я не прав ?





 
panov   (2002-06-26 14:33) [33]

>McSimm © (26.06.02 14:20)
Освобождения памяти от строки не произойдет
Почему? см. panov © (26.06.02 14:01)


 
valery_f   (2002-06-26 14:35) [34]

Насколько я помню, переменная типа string - это указатель на выделенную память. От этого адреса в "плюс" идет строка с нулем в конце (т.е. переменную можно использовать как PChar), а в обратную - служебная информация, включая длину строки и пр. (состав и формат служ. информации зависит от версии). Видимо там же расположен и счетчик ссылок.

Что касается освобождения памяти, то этим занимается дельфийский "сборщик мусора", т.е. s:="" память, скорее всего, мгновенно не освободит. Однако заморачиваться по этому поводу не стОит, т.к. этих "сборщиков" - целая куча и в винде (к примеру - высвобождение хэндлов после обнуления счетчика ссылок на них), и в дельфи (строки, COM-объекты и пр.) и всё пока что работает. Во всяком случае, по результатам тестов дельфи делает VB, C#, VC++ и Intel C++ по скорости и качеству работы с памятью.


 
McSimm   (2002-06-26 14:40) [35]

Все немножко (самую малость) сложнее. Попробую объяснить.
Как я уже написал,
> тут все зависит от того способа каким это строка создана


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

AStr - указатель на выделенный блок памяти 4 байта.
В этих четырех байтах хранится указатель на строку.

Конкретно в приведенном примере AStr^ := "hello, world !"
вообще не будет выделяться память под строку - она уже есть в сегменте данных и AStr^ просто получит на нее указатель.

В другом случае, напр. AStr^ := IntToStr(12345) будет создана строка "12345" динамически, но счетчик испоьзования увеличен не будет, сколько указателей на нее бы не ссылались. Строка будет уничтожена компилятором при выходе из процедуры, не зависимо от того освободите ли вы память от указателей или нет.


 
Viewer   (2002-06-26 14:42) [36]

Я уже предложил вопрошающему проверку.
Viewer (26.06.02 14:02)

При s:="" память очень даже освобождается и в Win98

>valery_f (26.06.02 14:35)
>Во всяком случае, по результатам тестов дельфи делает VB, C#, >VC++ и Intel C++ по скорости

Вот здесь не надо ля-ля. На строках именно паскаль и тормозит.


 
Skier   (2002-06-26 14:53) [37]

> McSimm
Т.е. код ошибочен, даже если
писать

AStr^ := "hello, world !";
AStr^ := "";

??????


 
McSimm   (2002-06-26 15:04) [38]

Смотря как посмотреть :)

Собственно ошибки тут нет.
AStr^ := ""; - корректно освободит память от строки
FreeMem - освободит память от указателя



 
Skier   (2002-06-26 15:11) [39]

> McSimm
А всё-таки ?

А если это будет не строка а скажем Varinant и
будет использоваться соотв-но
PVariant = ^Varinant, будет тоже самое или как ??
(Имею в виду memory leak)



 
McSimm   (2002-06-26 15:12) [40]

Чтобы понятнее было почему компилятор не должен освобождать строку, можно проделать такой опыт:

AStr := AllocMem(4);
// AStr^ := "hello, world !";
Pointer(AStr^) := Pointer(123456); // произвольные 4 байта
FreeMem(AStr, 4);

Ошибки нет. Все будет работать. Только потому, что программа не будет пытаться освободить строку по отфонарному адресу



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

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

Наверх





Память: 0.54 MB
Время: 0.011 c
7-47847
Makor
2002-04-25 12:08
2002.07.15
Где взять русскую документацию по WDM


3-47105
jaric
2002-06-20 19:34
2002.07.15
Как переиндексировать dbf таблицу?


1-47580
Aleksandr
2002-06-28 13:50
2002.07.15
Как объявить процедуру, универсальную для разных объектов?


3-47126
NaPoleOn_IV
2002-06-22 21:38
2002.07.15
Дорогие мастера, подскажите


1-47573
Board
2002-06-27 20:30
2002.07.15
HexToInt





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский