Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Ошибка при возврате очень большой строки


Автор: CynicRus 31.5.2013, 09:47
Ещё раз приветствую уважаемых форумчан. Преобразовываю массив структур в троку, всё здорово. А вот при попытке присвоить значение этой строки какой либо переменной приводит к Access Violation at 0x0040538c: read of address 0x00000008. При этом строка может быть достаточно большой, но до 2 гигабайт точно не дотягивает.

Собственно код преобразования в строку:

Код

var
  i : integer;
  DestLen : longword;
  DataStr,S : string;
  CorrectData : TRGB24Array;
begin
  SetLength(DataStr,w*h*3);
  CorrectData:= TRGB24Array(@DataStr[1]);
  for i := w*h - 1 downto 0 do
  begin
    CorrectData[i].R := FData^[i].R;
    CorrectData[i].G := FData^[i].G;
    CorrectData[i].B := FData^[i].B;
  end;
  if compress(pbyte(BufferString),destlen,Pbyte(DataStr),w*h*3) = Z_OK then
  begin;
    SetLength(DataStr,DestLen);
    move(bufferstring[0],dataStr[1],DestLen);
    s := 'm' + Base64EncodeStr(datastr);
    SetLength(datastr,0);
  end;
  Result:=S;
end;

На выходе, в отладчике я вижу что значение присвоилось. Строка длинная. А вот начинаю в тексте программы пытаться присоить значение из этой функции, и получаю вышеизложенно. Работаю в Delphi XE и Delphi XE 3, и в обеих средах получаю такое поведение. Ну и вопрос, собственно - как присвоить значение из этой функции строковой переменной без ошибки.

Добавлено через 7 минут и 38 секунд
Так...дальнейшая отладка показала, что ошибка происходит при попытке освободить временный массив CorrectData. DataStr - освобождается, а вот CorrectData - видимо ошибка и происходит, когда уничтожается эта локальная переменная. И чего тут делать - пока ума не приложу.

Автор: Чучмек 31.5.2013, 09:59
А какая необходимость использовать строку?

Автор: CynicRus 31.5.2013, 10:14
Цитата(Чучмек @ 31.5.2013,  09:59)
А какая необходимость использовать строку?

Совместимость. Хотя я сейчас пробую отказаться от временного массива, и работать с указателем на массив...Но дела идут не очень:)

Код

var
  i : integer;
  DestLen : longword;
  DataStr : PRGB24;
  CorrectData : TRGB24;
  Procedure WriteRGB24(Data: TRGB24);
   begin
     PRGB(DataStr)^ := Data;
     Inc(PRGB(DataStr),SizeOf(TRGB24))
   end;
begin
 // CorrectData:= TRGB24Array(@DataStr[1]);
  for i := w*h - 1 downto 0 do
  begin
    CorrectData.R := FData^[i].R;
    CorrectData.G := FData^[i].G;
    CorrectData.B := FData^[i].B;
    WriteRGB24(CorrectData);
  end;
  if compress(pbyte(BufferString),destlen,Pbyte(DataStr),w*h*3) = Z_OK then
  begin;
    SetLength(Result,DestLen);
    move(bufferstring[0],result[1],DestLen);
    Result := 'm' + Base64EncodeStr(result);
   // SetLength(DataStr,0);
  end;
end;

Автор: DarkProg 3.6.2013, 22:47
Зачем вы динамическому типу string пытаетесь задать длину строки функцией SetLength?
Delphi сама выделит память, если требуется, просто инициализируйте переменную, а потом используйте s:=s+'чего-то там'.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//object-id51a847a96ccc198e1f000002#findElement_E7045_51acf2c86ccc1974750003bd_0

Автор: DarkProg 3.6.2013, 22:52
Я вам рекомендую преобразовывать не в строку, а в TStringList, а потом можете спокойно взять TStringList.Text и получите одну строку.
Причём организация будет типа как в обычном блокноте.

Приведите более полный код, потому что у меня такое ощущение, что есть лишние операции у вас с указателями.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com//object-id51a847a96ccc198e1f000002#findElement_E7045_51acf4066ccc197b7500065d_0

Автор: northener 4.6.2013, 00:54
Цитата(CynicRus @  31.5.2013,  10:14 Найти цитируемый пост)
move(bufferstring[0],result[1],DestLen);

Почему bufferstring[0]?

Автор: CynicRus 11.6.2013, 10:45
Цитата

Почему bufferstring[0]?


Потому что bufferstring - PChar.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)