Здравствуйте!
Вопрос у меня вот в чем.
Как то не приходилось работать с указателями. Почитав материал вроде все понятно. Получить адрес, разыменовать указатель. Но вот на практике, что-то не то. Или потому что нет самой практики в этой теме.
К примеру вот такая запись:
Код:
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.
В чем может быть ошибка? не правильно использую указатели?
Подскажите как правильно должно быть.