Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Странное поведение SetLength / 14 сообщений из 14, страница 1 из 1
26.05.2017, 23:56:14
    #39460724
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
Доброй ночи!
Обнаружилось странное поведение SetLength. Странность в том, что при увеличении размера существующей строки в ней может появится мусор.
Вот тут пишут:
http://www.delphibasics.ru/SetLength.php

авторЕсли строка короче, то она отсекается. Если она длиннее, то добавленные символы не будут проинициализированы. Это может дать странный эффект - смотрите первый пример.

У меня проявляется в IBX'ах. Они забирают строку из буфера базы, дальше делают такой финт, увеличивая длину Result (она изначально получается меньше из-за конвертации UTF8 > Unicode):

Код: pascal
1.
2.
        if FXSQLVAR.SqlDef = SQL_TEXT then
          SetLength(Result, str_len div GetCharSetSize);



и на выходе AsString можно получить немного мусора в конце строки. После разбирательств, выяснилось, что SetLength вызывает _NewUnicodeString, который вызывает GetMem, который не заполняет память нулями. На выходе может получится (и получается) мусор. Проблеме больше подвержен 64х битный режим.

Сталкивался ли кто-то с таким поведением? У меня Delphi XE6.
...
Рейтинг: 0 / 0
27.05.2017, 00:04:44
    #39460728
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
makhaonСталкивался ли кто-то с таким поведением?
Дока же:
For a long string variable, SetLength reallocates the string referenced by S to the given length. Existing characters in the string are preserved, but the content of newly allocated space is undefined .
...
Рейтинг: 0 / 0
27.05.2017, 00:12:20
    #39460731
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
Kazantsev Alexey,

замечательно :) и что делать? IBX'ы править?
...
Рейтинг: 0 / 0
27.05.2017, 00:53:14
    #39460738
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
Обратитесь к разработчику. (с)
...
Рейтинг: 0 / 0
27.05.2017, 08:13:55
    #39460758
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
Разработчик известно что посоветует :) Обновиться до последней версии, конечно небесплатно. Поступил проще - поправил сырцы IBX.
...
Рейтинг: 0 / 0
27.05.2017, 09:54:36
    #39460776
schi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
makhaonДоброй ночи!
Обнаружилось странное поведение SetLength. Странность в том, что при увеличении размера существующей строки в ней может появится мусор.

А чем, по-твоему, правильная реализация SetLength должна была заполнять ?
...
Рейтинг: 0 / 0
27.05.2017, 09:59:19
    #39460778
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
schi,

Так как это строка, то могла бы заполняться пробелами. По-твоему лучше возвращать мусор из памяти? Медленнее, конечно, зато надёжнее. Как вариант - в опции, то есть - в параметры. Видишь - сами напарываются на свои же 'особенности'.
...
Рейтинг: 0 / 0
27.05.2017, 10:11:25
    #39460779
GunSmoker
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
makhaon, подозреваю, что по плану этот SetLength стоит там для varchar - укоротить строку из исходного буфера. Соответственно, предполагалось только уменьшение длины, и поэтому FillChar там нет. В случае же фиксированной длины поля получается незапланированное увеличение длины строки этим SetLength, если строка изначально была меньшего размера из-за UTF-8.
...
Рейтинг: 0 / 0
27.05.2017, 15:30:22
    #39460853
schi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
makhaonschi,

Так как это строка, то могла бы заполняться пробелами. По-твоему лучше возвращать мусор из памяти? Медленнее, конечно, зато надёжнее. Как вариант - в опции, то есть - в параметры. Видишь - сами напарываются на свои же 'особенности'.

По-моему, тот, кто вызывает SetLength должен сам заботиться о заполнении. Если он не заботится, то какой смысл в пробелах или нулях ?
...
Рейтинг: 0 / 0
27.05.2017, 15:57:49
    #39460862
Bred eFeM
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
makhaonзамечательно :) и что делать? IBX'ы править?
Код: pascal
1.
2.
3.
4.
5.
6.
var 
 Mm : TMemoryManagerEx;
begin
 GetMemoryManager(Mm);
 Mm.GetMem := Mm.AllocMem;
 SetMemoryManager(Mm);
...
Рейтинг: 0 / 0
27.05.2017, 16:03:13
    #39460864
чччД
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
makhaon,
а не используешь ли ты в базе поля типа varchar(...)? Ну, строковые поля фиксированной длины.
...
Рейтинг: 0 / 0
27.05.2017, 16:50:00
    #39460874
DimaBr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
makhaonТак как это строка, то могла бы заполняться пробелами.
Чем ПРОБЕЛ лучше другого символа ?
Зачем использовать SetLength, который просто устанавливает длину переменной, не заботясь об инициализвции ?
Сделайте конкейт нужого количества ПРОБЕЛОВ
...
Рейтинг: 0 / 0
27.05.2017, 19:15:23
    #39460902
makhaon
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
DimaBr,

То есть возвращать всегда неинициализированные кусок памяти лучше? Зачем писать заведомые потенциальные баги? В случае неинициализированных локальных переменных хотя бы предупреждения есть.

авторЕсли он не заботится, то какой смысл в пробелах или нулях

Ну а почему динамические массивы нулями заполняются? Давайте тогда, для общности, и их мусором забивать :) Чем именно строки провинились?

Код: pascal
1.
2.
3.
  // Set the new memory to all zero bits
  if newLength > oldLength then
    FillChar((PByte(p) + elSize * oldLength)^, elSize * (newLength - oldLength), 0);



Ничего, не свалилась корона :)

авторЧем ПРОБЕЛ лучше другого символа ?

Так не вопрос - можно было бы в SetLength передавать символ заполнения, по умолчанию - например - пробел, если передают '' - то работает как сейчас, если что-то другое - то другим заполняется. Если есть что-то более подходящее, чем пробел. Случаи всякие бывают. Мне пробел удобнее всего был бы.
...
Рейтинг: 0 / 0
27.05.2017, 19:55:21
    #39460913
чччД
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение SetLength
makhaon,

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

Заведи себе файлик MyUtils.pas, и вноси в него правильные с твоей т.зр. рутины, да в своих проектах юзай.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Странное поведение SetLength / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]