Страница 1 из 2

Проблемма с расходом памяти

Добавлено: 15 июн 2006, 01:11
Blood_Magic

Код: Выделить всё

type
  TShortInfo = record
    IsNew:string[1];
    Attribute:string[1];
    Size:string[12];
    DateTime:string[12];
    FileName:string[100];//????????Неизвестный размер
  end;

  TTree = class
  public
    DirName:string;
    Node:TTreeNode;
    Parent:TTree;
    SubDirs:array of TTree;
    Files:array of TShortInfo;
    constructor Create;
    destructor Destroy;override;
  end;
Если ставлю тип просто string, то Delphi принимает его как string[255] и на загрузку дерева уходит порядка 200Мб памяти. Если ставлю string[100] то порядка 70Мб, но встречаются более длинные имена. Как быть? Как можно еще описать? Если использовать другой тип, например, PChar, то у меня какие-то ошибки появляются, может я PChar в string потом неправильно преобразовываю.

Добавлено: 15 июн 2006, 10:32
Игорь Акопян
для PChar надо не забыть память выделять

Добавлено: 15 июн 2006, 11:56
Duncon
Можно представить массивом символов FileName: array of char; а там посмотреть что получиться...

Добавлено: 15 июн 2006, 13:51
Blood_Magic
[quote="Duncon"]Можно представить массивом символов FileName: array of char]

напомни как в string и обратно преобразовать

Добавлено: 16 июн 2006, 08:51
Duncon

Код: Выделить всё

function strtoPchar(s:string):Pchar;
begin
  S := S+#0;
  result:=StrPCopy(@S[1], S) ;
end;

или 

pch:=PChar(str);

Добавлено: 16 июн 2006, 14:07
vunder
В Delphgi тип String по-умолчанию имеет размер 65525 символов

Добавлено: 16 июн 2006, 15:20
Blood_Magic
а я всегда думал что 255

Добавлено: 16 июн 2006, 19:53
Duncon
нет, выделяемый по умолчанию размер 255, не нужно вводить в заблуждение,- типа стоит некоторым книжки почитать, а почему PChar советуем - так потому что он памяти меньше зажирает...

Добавлено: 17 июн 2006, 02:35
Naeel Maqsudov
На самом деле, давным давно в языке Pascal был тип String[N]. Значение N по умолчанию равнялось 255, так как внутренний формат представления String - LASCII, т.е. 1 байт на длину + массив Char-ов.

Delphi использует язык Object Pascal, в котором опрелделено 3 стандартных типа:
1) ShortString - аналог старого String
2) AnsiString - 2GB-ные ASCII строки (8-битные)
3) WideString - 2GB-ные UNICODE-строки

Идентификатор String в Object Pascal по умолчанию эквивалентен AnsiString, однако, для совместимости заставить компилятор интерпретировать String как ShortString (см директивы {$H–/+} и настройки компилятора (Project/Options))

Итак, скорее всего вы имеете дело с AnsiString. Разумеется 2GB не выделяется под переменную сразу. По формальным признакам выделяется столько, сколько нужно, но менеджер памяти видимо фрагментирует память (умышленно, чтобы не заниматься перераспределением памяти, если к строке прибавят несколько символов).

Есть еще тип OpenString, но его можно не брать в расчет вообще, он нужен только для совместимости, для вызова некоторых 16-разрядных функций WinAPI. (Если, скажем, Вы решите написать что-нибудь для Windows 3.11)

В Вашем случае, очевидно, не стоит полагаться на работу менеджера памяти с AnsiString....
AnsiString совместим с PChar настолько, что даже #0 в конце строки добавлять не надо.

Попробуйте использовать PChar(str), как советовал Duncon. Если результат останется прежним, то переделаем по-другому - будем выделять память из кучи ручками.

Добавлено: 17 июн 2006, 16:44
Blood_Magic
если просто заменить FileName:string[100]; на FileName:PChar;, то выдает ошибку, я так понял, GetMem использовать надо