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

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

Вернуться   Форум программистов > Клуб программистов > Обсуждение статей
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 25.10.2009, 05:47   #1
OCTAGRAM
Oldschool geek
Форумчанин
 
Аватар для OCTAGRAM
 
Регистрация: 09.03.2009
Сообщений: 611
По умолчанию Загадочный тип PChar, критика

Сабж: http://programmersclub.ru/typepchar/

Я писал ответ давно, но он по–прежнему awaiting moderation, так что скопирую его для тех, кто его не видит:
__________________
Много дезинформации. Хоть заново пиши.

Во–первых, нужно отличать турбо паскалевские строки от делфийских. В Turbo Pascal символьные данные хранятся целиком по месту объявления переменной. В Delphi строки обычно хранятся в динамической памяти, а в строковых переменных только указатели. Если использовать тип String[число], то для переменных этого типа включается старый способ хранения, доставшийся в наследство от Turbo Pascal. Также есть тип ShortString, эквивалентный String[255] в Delphi или String в Turbo Pascal. И ещё есть директива компилятора, включающая старый способ хранения строк.

Турбо Паскалескими строками имеет смысл заморачиваться только олимпиадникам. Один раз, помню, переключил строки на Паскалевские, и решение прошло по времени. Стек быстрее кучи.

Учитывая внезапно обнаружившуюся информацию, правим косяки:

Цитата:
Обращаться к 55 символу переменной str2 уже нельзя, но физически в памяти он существует.
Неправда, STR2 занимает 21 байт (1 байт длины + 20 байт под максимально длинную строку). Нету там 55го символа.

Цитата:
Не знаю почему, но вместо двоек выводится не пойми что. Мистика!!!
Жесть.

Отвечаю: потому что Str — это строка, размещённая в куче. На месте самой переменной хранится просто указатель на символьные данные. @STR, таким образом, указатель на указатель на символьные данные, в то время как ожидается указатель на символьные данные.

Строки нужно приводить к PChar, без всяких собак. Собаки — только для array[] of Char. Если какой–то функции нужно передать аргумент типа PChar и эта строка вычисляется выражением, например,

‘Осталось ждать минут: ‘ + IntToStr(EstimatedMin)

…то в этом случае нужно присвоить это значение временной переменной типа string, а уже потом вызывать функцию WinAPI. Всё это нужно затем, чтобы сохранялось владение памятью, в которой размещёны символьные данные. Наверное, если тайпкастить результат строкового выражения к PChar, Delphi мог бы не высвобождать строку до окончания выполнения функции, но я сомневаюсь в том, что это реализовано. Может получиться висячий указатель, так что лучше использовать временную строковую переменную.
__________________
Желательно всё же что–нибудь сделать с этой статьёй. Нельзя, чтобы статью с такой кучей ляпов кто–нибудь всерьёз пытался использовать как достоверный источник.
If you want to get to the top, you have to start at the bottom

http://pascal.net.ru/
OCTAGRAM вне форума Ответить с цитированием
Старый 25.10.2009, 17:03   #2
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

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

Последний раз редактировалось rpy3uH; 25.10.2009 в 17:08.
rpy3uH вне форума Ответить с цитированием
Старый 01.11.2009, 16:57   #3
OCTAGRAM
Oldschool geek
Форумчанин
 
Аватар для OCTAGRAM
 
Регистрация: 09.03.2009
Сообщений: 611
По умолчанию

Черновик здесь: http://octagram.ya.ru/replies.xml?item_no=64

Есть спорные моменты, в частности, можно ли писать так. Нужно посмотреть, какой ассемблерный код в старых Делфях генерируется для процедуры:

Код:
procedure NotifyRemain(mins : Integer);
begin
   MessageBox(0, PChar('Осталось ' + IntToStr(mins) + ' мин'), 'Внимание!', MB_OK);
end;
http://programmersforum.ru/showthread.php?t=68646
If you want to get to the top, you have to start at the bottom

http://pascal.net.ru/

Последний раз редактировалось OCTAGRAM; 01.11.2009 в 17:03.
OCTAGRAM вне форума Ответить с цитированием
Старый 01.11.2009, 21:44   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

не совсем понял, что это даст..
но Delphi 5 достаточно старая?


(в принципе есть и самая древняя Delphi генерящая код для Win32 - это Дельфи3, можно достать из архива)
Serge_Bliznykov вне форума Ответить с цитированием
Старый 11.11.2009, 10:25   #5
OCTAGRAM
Oldschool geek
Форумчанин
 
Аватар для OCTAGRAM
 
Регистрация: 09.03.2009
Сообщений: 611
По умолчанию

Прикольно. Наглядно видно, что освобождение строки (LStrArrayClr) происходит после вызова MessageBox, а не до. Всё работает так, как хотелось бы.
If you want to get to the top, you have to start at the bottom

http://pascal.net.ru/
OCTAGRAM вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Загадочный NMSMTP InseR Работа с сетью в Delphi 5 13.02.2009 08:14
Профессиональная критика биопрограмм doctor-tv Софт 3 24.01.2009 12:08
Перевести тип String в тип PChar (Delphi 7) ScorpioN_T Помощь студентам 2 28.10.2008 22:13
загадочный цикл semantics Общие вопросы Delphi 2 30.05.2008 14:00
Access violation на строке вида StrLCopy(PChar(st1),PChar(st2),10); malor Общие вопросы Delphi 1 11.07.2007 13:39