Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
 Аватар для noname_club
112 / 103 / 12
Регистрация: 01.05.2013
Сообщений: 603

работа с указателями Pchar

03.11.2013, 12:17. Показов 2146. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
имеется код
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
type
 
  pstr = ^UnicodeString;
 
var
  Form1: TForm1;
 
  k1:pointer;
  k2:pointer;
 
implementation
 
{$R *.dfm}
 
// Сохранение через указатель на строку
 
procedure TForm1.Button1Click(Sender: TObject);
var s:UnicodeString;
begin
  //
  s:='1привет мир';
  k1:=@s;
  MessageBoxW(self.Handle,@pstr(k1)^[1],'',0);
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  MessageBoxW(self.Handle,@pstr(k1)^[1],'',0);  // ошибка, что в принципе нормально
end;
 
// Сохранение через указатель PChar
 
procedure TForm1.Button3Click(Sender: TObject);
var s:UnicodeString;
begin
  s:='2привет мир';
  k2:=@s[1];
  MessageBoxW(self.Handle,k2,'',0);
end;
 
procedure TForm1.Button4Click(Sender: TObject);
begin
  MessageBoxW(self.Handle,k2,'',0);  // НЕТ ОШИБКИ, ПОЧЕМУ?
end;


в первом случае при нажатии на первую(Button1Click) а потом на вторую кнопку (Button2Click) появляется ошибка, а точнее exception

во втором случае при нажатии на первую(Button3Click) а потом на вторую кнопку (Button4Click)
ошибка не появляется, что весьма странно, ибо на строку больше нет указателей, кроме pointer указателя, и теоретически она должна быть уничтожена, однако это не происходит

хочу разобраться, почему при сохранении указателя на начало строки (2 случай), строка продолжает жить и не уничтожается?

Вложения
Тип файла: zip testPcharMem.zip (931.5 Кб, 0 просмотров)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.11.2013, 12:17
Ответы с готовыми решениями:

Работа с указателями
Здравствуйте! Помогите пожалуйста,не могу разобраться с указателями. Как сделать так,что бы при в воде в edit какого-то текста, а с друого...

Работа с указателями
Есть объект (студент) с полями, в которых расположены имя и оценки. Создан объект(база данных) с полем динамического массива из...

Работа с указателями. Упорядочный список.
Срочно , плиз!! Помогите дописать Упорядочный список используя указатели

6
 Аватар для noname_club
112 / 103 / 12
Регистрация: 01.05.2013
Сообщений: 603
03.11.2013, 12:49  [ТС]
справочный материал http://www.transl-gunsmoker.ru/2009/09/pchars.html

Добавлено через 28 минут
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// Сохранение через указатель на строку
 
procedure TForm1.Button1Click(Sender: TObject);
var s:UnicodeString;
begin
  //
  s:='1привет мир';
  k1:=@s[1];
  MessageBoxW(self.Handle,k1,'',0);
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  MessageBoxW(self.Handle,k1,'',0); // пусто или не пусто
 
end;
решил по-нажимать раз этак 10, Button1Click->Button2Click

выяснилось что в некоторых случаях на экране появляется пустое сообщение => строка все же уничтожена

далее вынесем строку в глобальную переменную

и естественно результат будет всегда правильный

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var
  Form1: TForm1;
 
  k1:pointer;
  k2:pointer;
 
  globalstr: UnicodeString; // глобальная строка
 
implementation
 
{$R *.dfm}
 
 
procedure TForm1.Button1Click(Sender: TObject);
var s:UnicodeString;
begin
  //
  s:='1привет мир';
  globalstr:=s;
  k1:=@globalstr[1];
  MessageBoxW(self.Handle,k1,'',0);
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  MessageBoxW(self.Handle,k1,'',0); // Всегда верно
end;
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
03.11.2013, 20:03
По вопросам из заглавного поста темы.

Цитата Сообщение от noname_club Посмотреть сообщение
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var
  Form1: TForm1;
 
  k1:pointer;
  k2:pointer;
 
implementation
 
{$R *.dfm}
 
procedure TForm1.Button1Click(Sender: TObject);
var s:UnicodeString;
begin
  s:='1привет мир';
  k1:=@s;
  MessageBoxW(self.Handle,@pstr(k1)^[1],'',0);
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
  MessageBoxW(self.Handle,@pstr(k1)^[1],'',0);  // ошибка, что в принципе нормально
end;
в первом случае при нажатии на первую(Button1Click) а потом на вторую кнопку (Button2Click) появляется ошибка, а точнее exception
Строка '1привет мир' - это константа. Константы расположены в области статических данных программы - в сегменте данных. Это означает, что константы существуют на всём протяжении работы программы. В процессе работы программы они не исчезают, соответственно.
В методе TForm1.Button1Click() происходит следующее. Константа '1привет мир', как я уже говорил - это неуничтожимые данные. При выполнении 14 строки кода:
Delphi
14
  s:='1привет мир';
в переменную S записывается указатель на область памяти, в которой расположен первый символ константной строки '1привет мир'.
Далее, при выполнении 15 строки кода:
Delphi
15
  k1:=@s;
В переменную k1 записывается указатель на переменную S. Подчеркну - записывается не указатель на строку '1привет мир', а указатель на переменную S. Переменная S содержит указатель на строку '1привет мир', а в переменной k1 записан указатель на указатель. Так вот, переменная S является локальной переменной, объявленной в методе TForm1.Button1Click(). И когда произойдёт выход из метода TForm1.Button1Click(), то переменная S перестанет существовать. Поэтому указатель k1 теперь будет указывать на несуществующую переменную. Поэтому, когда будет вызван метод TForm1.Button2Click(), то при переходе по адресу, записанному в k1, возникнет ошибка.

Теперь следующий код, где ошибка не возникает:
Цитата Сообщение от noname_club Посмотреть сообщение
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
procedure TForm1.Button3Click(Sender: TObject);
var s:UnicodeString;
begin
  s:='2привет мир';
  k2:=@s[1];
  MessageBoxW(self.Handle,k2,'',0);
end;
 
procedure TForm1.Button4Click(Sender: TObject);
begin
  MessageBoxW(self.Handle,k2,'',0);  // НЕТ ОШИБКИ, ПОЧЕМУ?
end;
во втором случае при нажатии на первую(Button3Click) а потом на вторую кнопку (Button4Click)
ошибка не появляется, что весьма странно, ибо на строку больше нет указателей, кроме pointer указателя, и теоретически она должна быть уничтожена, однако это не происходит
Здесь, строка '2привет мир' - это тоже константа - неуничтожимый объект. А ошибка не возникает потому, что теперь в k2 записан не указатель на локальную переменную S, а указатель на строку '2привет мир'. Именно поэтому ошибок не возникает.
В строке:
Delphi
5
  k2:=@s[1];
происходит следующее. В переменную k2 записывается адрес, по которому расположен первый символ строки '2привет мир'. Это тот же самый адрес, который записан в переменной S. Можно было бы написать так:
Delphi
5
  k2 := Pointer(s);
1
 Аватар для noname_club
112 / 103 / 12
Регистрация: 01.05.2013
Сообщений: 603
04.11.2013, 01:05  [ТС]
иными словами тут идет влияние литералов компилятора на процессы образования строк
то есть если бы строка создавалось не из строкового литерала '2привет мир' который у компилятора уже записан как константа, то во всех случаях было бы пустое сообщение в результате?
0
 Аватар для Mawrat
13114 / 5895 / 1708
Регистрация: 19.09.2009
Сообщений: 8,809
04.11.2013, 01:16
Цитата Сообщение от noname_club Посмотреть сообщение
иными словами тут идет влияние литералов компилятора на процессы образования строк
Литералы - это на самом деле неименованные константы. Константы находятся в статической памяти постоянно - на протяжении всего времени, пока работает программа.
Цитата Сообщение от noname_club Посмотреть сообщение
то есть если бы строка создавалось не из строкового литерала '2привет мир' который у компилятора уже записан как константа, то во всех случаях было бы пустое сообщение в результате?
Да, или возникла бы ошибка доступа к памяти. Можно проверить таким образом:
Delphi
1
2
3
4
5
6
7
8
9
procedure TForm1.Button3Click(Sender: TObject);
var s:UnicodeString;
begin
  s:='2привет мир';
  //Создаём отдельный экземпляр строки в динамической памяти.
  UniqueString(s);
  k2:=@s[1];
  MessageBoxW(self.Handle,k2,'',0);
end;
Вот теперь вызов TForm1.Button4Click() приведёт к ошибке:
Delphi
1
2
3
4
procedure TForm1.Button4Click(Sender: TObject);
begin
  MessageBoxW(self.Handle,k2,'',0);
end;
Потому что указатель k2 ссылается на строковую переменную, которая является локальной в методе TForm1.Button3Click(). Как только происходит выход из метода TForm1.Button3Click(), то переменная S перестаёт существовать и указатель k2 с этого момента ссылается на несуществующие данные.
1
пофигист широкого профиля
4769 / 3204 / 862
Регистрация: 15.07.2013
Сообщений: 18,612
04.11.2013, 02:14
Кстати название топика весьма отличается от его сути. Ибо никаких PChar в вопросе нет. А работа с PChar (взаимодействие с дельфийскими строками) производится мягко говоря совсем иначе. И подобных проблем не создаёт.
0
 Аватар для noname_club
112 / 103 / 12
Регистрация: 01.05.2013
Сообщений: 603
04.11.2013, 03:05  [ТС]
Ибо никаких PChar в вопросе нет
суть в том что @s[1] это прямой указатель на PChar без копирования памяти

И подобных проблем не создаёт
проблем как бы нет. Просто хотелось отследить наглядно уничтожение строки. Тема создавалась просто для выяснения самого факта что строки все таки уничтожаются.

Применение таким прямым указателям Pсhar на строку обсуждается в этой теме. DLL экспорт строк
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
04.11.2013, 03:05
Помогаю со студенческими работами здесь

Работа с Pchar
Добрый день! У меня есть задача. Hанее почти не работал с PChar. Помогите разобраться. В длл есть функция: GetCfgData(var...

Кто может улучшить конструкцию. Работа с указателями
var B: TBytes; source:string; i:word; begin Source := 'Какой-то текст.'; SetLength (B, sizeof(Char) *...

Создание списков. Работа с указателями. Настройка указателей списка. Delphi
Всем доброго времени суток! Есть небольшая трудность, а заключается она в том, что я не могу правильно настроить указатели списка...

Pchar из dll
в общем, требуется написать UDF под интербазу, катаем dll library UDFStr2; // uses // SysUtils; function...

Pchar и освобождение памяти
Здравствуйте. Написал парсинг страницы сайта. Запрос страницы идёт из основной программы, после чего полученная строка передаётся в dll...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru