Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.06.2022, 12:42   #1
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию Несколько вопросов про строки

В Паскале длина строки была 255 символов, а нулевой символ был равен ее длине
В Дельфи строки неограниченной длины, как я понял. Что вызывает вопрос: а как под строку выделяется память? Когда неизвестно сколько надо выделять из-за неограниченности длины
Kronos913 вне форума Ответить с цитированием
Старый 21.06.2022, 13:28   #2
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию

Эти вопросы имеют отношение к обращению к строке через asm

(Адрес строки + номер элемента - 1) всегда ли будет верным адресом символа?
Kronos913 вне форума Ответить с цитированием
Старый 21.06.2022, 14:34   #3
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
В Дельфи строки неограниченной длины, как я понял. Что вызывает вопрос: а как под строку выделяется память?
Строки выделяются через менеджер динамически распределяемой памяти. Хотя (теоретически) одна строка и допускает размер в 2 Гб, но практически она ограничена размером блока кучи (блока из которого выделяется память кусочками).
Строение типа String на Delphi может быть разным от версии к версии. Например в Lazarus тип String напрямую описывается как класс. В Delphi 7 версии однако подобного описания типа String я не находил (хотя, возможно, и там такое было). Поэтому работать напрямую с типом String не стоит. Не говоря уже про сборщик мусора, который следит за высвобождением памяти от динамических объектов/классов.

Если хотите работать со строками, тогда лучше используйте тип PChar/PAnsiChar/PWideChar. В этом случае строки представляются как массив символов начинающихся с 0 индекса и оканчиваются символом с кодом #0. Эти типы как раз предусмотрены для взаимодействия с внешними программами и максимально упрощают структуры связанные с ЯП Pascal в них.

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
(Адрес строки + номер элемента - 1) всегда ли будет верным адресом символа?
Для строк типа PChar этот адрес будет (Адрес строки + номер элемента)
macomics вне форума Ответить с цитированием
Старый 21.06.2022, 17:41   #4
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию

А если мне нужна строка паскалевского типа, надо объявлять ее string[255] ?
Kronos913 вне форума Ответить с цитированием
Старый 21.06.2022, 18:49   #5
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
А если мне нужна строка паскалевского типа, надо объявлять ее string[255] ?
Да. Тогда создается массив со счетчиком вместо первого элемента. Еще были ShortString
macomics вне форума Ответить с цитированием
Старый 07.09.2022, 23:09   #6
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию

Чтобы не создавать новую тему, пишу вопрос тут.

А как выделяется память под строку? Учитывая ее неограниченность.
Если я через SetLength увеличу длину, то не затрет ли тогда строка какие-то другие данные?

Или у "неограниченной" строки тоже есть лимит и под него уже выделена полностью память?
Kronos913 вне форума Ответить с цитированием
Старый 08.09.2022, 00:16   #7
northener
ПШП
Участник клуба
 
Регистрация: 15.07.2013
Сообщений: 1,859
По умолчанию

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
А как выделяется память под строку? Учитывая ее неограниченность.
Если я через SetLength увеличу длину, то не затрет ли тогда строка какие-то другие данные?
Выделяется новый кусок памяти нужного размера и туда копируется прежнее содержимое. Так что не затрет.
northener вне форума Ответить с цитированием
Старый 08.09.2022, 00:22   #8
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию

Получается, тогда может измениться адрес, где находится эта строка? И где тогда искать новый адрес? Если через asm
Kronos913 вне форума Ответить с цитированием
Старый 08.09.2022, 00:38   #9
Kronos913
Форумчанин
 
Регистрация: 10.02.2021
Сообщений: 603
По умолчанию

Такой код выдаёт ошибку при исполнении
Код:
Function fff:string; register
asm
  push ebx
  mov eax, result

  mov edx, 1000
  call system.@LStrSetLength

  mov bl, 49
  mov ecx, 1000
  @Begin1:
    mov [eax], bl
    dec ecx
    inc eax

    cmp ecx, 0
      ja @Begin1
  pop ebx
end;
Kronos913 вне форума Ответить с цитированием
Старый 08.09.2022, 00:49   #10
macomics
Участник клуба
 
Регистрация: 17.04.2022
Сообщений: 1,833
По умолчанию

Не стоит играться с этими объектами на asm. Они завязаны на более сложные алгоритмы и на asm вы вручную чокнитесь постоянно выполнять все необходимые манипуляции со строками.

Память на 1 этапе резервируется на уровне страниц в виртуальном адресном пространстве в виде кучи. Далее по мере использования из этой кучи будут выделяться блоки нужной длины, но все же длина кучи ограничена (как минимум виртуальным адресным пространством), но как правило не более чем 16 - 64 Мб. Если надо больше, тогда проще выделить сразу виртуальную память.

Куча все же предназначена для объектов типа строк, массивов или структур, которые условно не ограничены. Естественно менеджер кучи при выделении блоков следит, чтобы они не пересекались, поэтому, если вы не вылезете за пределы выделенного вам участка, тогда и не затрете ничего.

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

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

Цитата:
Сообщение от Kronos913 Посмотреть сообщение
Такой код выдаёт ошибку при исполнении
Потому, что cтроку типа String надо сначала выделить. Изначально у вас нету вообще блока памяти и указатель, скорее всего, равен nil.

Последний раз редактировалось macomics; 08.09.2022 в 00:53.
macomics вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Несколько вопросов по ИС Niddin_hp Помощь студентам 0 22.11.2015 21:06
Несколько вопросов Rost93 PHP 18 19.09.2012 19:38
Несколько вопросов по C++ Antitime Общие вопросы C/C++ 10 26.01.2012 15:00
несколько вопросов spydark91 Общие вопросы Delphi 2 18.07.2011 13:48
несколько вопросов fitc Общие вопросы Delphi 28 14.07.2009 21:20