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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 06.05.2015, 01:20   #1
crossmark
Пользователь
 
Регистрация: 13.03.2010
Сообщений: 27
По умолчанию Указатели от теории к практике

Здравствуйте!

Вопрос у меня вот в чем.
Как то не приходилось работать с указателями. Почитав материал вроде все понятно. Получить адрес, разыменовать указатель. Но вот на практике, что-то не то. Или потому что нет самой практики в этой теме.
К примеру вот такая запись:
Код:
type
  TMass = array of byte;
  PMass = ^TMass;
End;
Я так это понял. Объявил тип: TMass массив байтов. Потом объявил PMass который является указателем на Tmass.
Это верно?

Я создаю класс - поток. Стандартный Tthread. TClientReadWriteData = class(TThread)
Код:
type
  TMass = array of byte;
  PMass = ^TMass;
  TClientReadWriteData = class(TThread)
  private
	bf: PMass;  //- объявил буфер котрый является указателем на Tmass
bf_size: integer;
Это верно?

Выделяю память
Код:
constructor TClientReadWriteData.Create;
begin
inherited Create(true);
bf_size:=32768;
//new(bf); // я делал сначала так
//SetLength(bf^, bf_size*sizeof(byte));  // так как это динамический массив. Выделил память
//указателю, потом память под массив

  GetMem(bf, bf_size*sizeof(byte));	// потом сделал так
end;
Мне вот интересна запись в комментарии. Что такое bf. new(bf); Создается переменная указатель. По какому то адресу. Потом SetLength(bf^,….) по этому адресу будет находится адрес массива… Так?
А вот GetMem – сразу выделил память для bf

Далее процедура потока.
Код:
procedure TClientReadWriteData.Execute;
var s: string;
begin
s:= string(pointer(bf));	// проверяю для себя
end;
Вот что заметил. Когда выделял bf через New и SetLength, то переменная s получала значения несколько (примерно около 10) мусорных символов, а вот когда через GetMem то было много мусорных символов.
Код:
procedure TClientReadWriteData.Execute;
var s: string;
begin
//s:= string(pointer(bf));	// проверяю для себя
sz:= recv(_ClientSocket, bf^, bf_size, 0);
s:= string(pointer(bf));
 s:= string(@bf);
end;
Теперь s получает значение которые прочитал сокет. Опять же. Если через New что там не вся строка. А несколько символов. Если Через GetMem – то тут будет вся строка + после нее мусор. (но этот мусор понятен).
Очень интересна строчка s:= string(@bf); тут вся строка – но вначале несколько символов мусора.

Потом идет чтение и запись. Фрагмент кода
Код:
procedure TClientReadWriteData.Execute;
var s: string;
begin
sz:= recv(_ClientSocket, bf^, bf_size, 0);
//код
While true do
Begin
	_size := recv(_ClientSocket, bf^, bf_size, 0);
	//код
send(_ServerSocket, bf^, _size, 0);
End;
end;
В какой то момент в каком то потоке получается не существующий адрес.
Может прокси нормально отработать. Загрузить страницу – одну – две. А может на первой странице вылетит ошибка Access Violation.
Я много раз просматривал и вот что когда для bf выделяется память на номера 118…-120..-130.. все работает, а вот когда на 400… то ошибка.
И что странно выпадает не при первом чтение (до цикла while) а вот уже в самом цикле while.

В чем может быть ошибка? не правильно использую указатели?
Подскажите как правильно должно быть.
Изображения
Тип файла: jpg error.jpg (8.0 Кб, 114 просмотров)
crossmark вне форума Ответить с цитированием
Старый 06.05.2015, 08:58   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Сделай bf локальной для TClientReadWriteData.Execute
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 06.05.2015, 09:45   #3
crossmark
Пользователь
 
Регистрация: 13.03.2010
Сообщений: 27
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Сделай bf локальной для TClientReadWriteData.Execute
делал в самом начале локальной
crossmark вне форума Ответить с цитированием
Старый 06.05.2015, 11:37   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

"смешались в кучу кони, люди.." // эпиграф

а что, никого не смущает, что
Цитата:
Код:
 TMass = array of byte;
TMass - это УКАЗАТЕЛЬ ?!!

и чтобы работать с динамическим массивом, нужно выделять память с помощью SetLength ?!

я бы сделал так:

Код:
  bf_size:=32768;
  new(bf); // я делал сначала так
  SetLength(bf^, bf_size);  // так как это динамический массив. Выделил память указателю, потом память под массив

... 
   recv(_ClientSocket, bf^[0], bf_size, 0);
но зачем Вам УКАЗАТЕЛЬ, который указывает на УКАЗАТЕЛЬ, мне лично совсем не понятно!

Последний раз редактировалось Serge_Bliznykov; 06.05.2015 в 11:43.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 06.05.2015, 11:42   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Где у Вас в коде SetLength ?!
Автор вроде упомянул что делает это.
Или делал?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 06.05.2015, 11:54   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Автор вроде упомянул что делает это.
Или делал?
угу. судя по комментариям делал. но ему это чем-то не понравилось.
И тогда пошли танцы/пляски...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 06.05.2015, 13:50   #7
SQLPowerUser
Форумчанин
 
Аватар для SQLPowerUser
 
Регистрация: 19.01.2015
Сообщений: 158
По умолчанию

crossmark,
на всякий случай - хорошая статья, держу у себя в закладках http://www.transl-gunsmoker.ru/2009/09/blog-post.html
SQLPowerUser вне форума Ответить с цитированием
Старый 06.05.2015, 14:23   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

SQLPowerUser, отличная статья!!!


кстати, не знаю, обратил автор темы внимание или нет, но я подчеркну цитату из своего поста:
Цитата:
Код:
 recv(_ClientSocket, bf^[0], bf_size, 0);
Serge_Bliznykov вне форума Ответить с цитированием
Старый 07.05.2015, 13:16   #9
crossmark
Пользователь
 
Регистрация: 13.03.2010
Сообщений: 27
По умолчанию

большое спасибо
crossmark вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
задания по практике 25-й кадр Помощь студентам 4 06.12.2013 17:04
Что такое ADSL ,не на теории ,а на практике viktor8888 Свободное общение 14 02.04.2013 21:22
Задание по практике IPI Помощь студентам 4 15.06.2010 12:31
Отчот по практике sby Фриланс 3 12.05.2009 17:16
[C] массивы, указатели, двойные указатели. Iggel Общие вопросы C/C++ 5 05.05.2009 12:39