GetMem отдает сырую, неинициализированную память, а для работы с интерфейсами/строками/дин массивами/вариантами память должна быть инициализирована. Вобщем заведи привычку под типизированные указатели выделять память через New, а освобождать через Dispose
J>используй New(TempSurf) вместо GetMem
J>GetMem отдает сырую, неинициализированную память, а для работы с интерфейсами/строками/дин массивами/вариантами память должна быть инициализирована. Вобщем заведи привычку под типизированные указатели выделять память через New, а освобождать через Dispose
U>В Чём разница:
U>вариант 1.... работает, потому что Data в этом случае и так равна Nil U>вариант 2.... Не работает потому что Data в этом случае заполнена мусором
А любое присвоение переменной типа интерфейс
Surface.Data := NewValue;
превращается в
if Surface.Data<>Nil then Surface.Data._Release();
Surface.Data := NewValue;
if Surface.Data<>Nil then Surface.Data._AddRef();
Кроме того, если сради локальных переменных ( или полей
структур локальных переменных) процедуры есть интерфейсного типа,
то Delphi оборачивает тело процедуры примерно в такой код
var
Surface : TSurface;
begin
Surface.Data:=Nil; //<<--try//<<--
(*
всё
что
вы
напишете
сами
*)finally//<<-- if Surface.Data<>Nil then//<<--
Surface.Data._Release(); //<<--end; //<<--end;
При выделении памяти через New, тоже добавляется код,
отвечающий за инициализацию таких полей, поскольку есть ссылка на тип.
А GetMem только выделяет память и никак её не инициализирует.
Либо используй AllocMem, либо сам чисти выделенный блок FillChar(TempSuff^, SizeOf(TSurface)). После чего TempSuft^.Data := NIL делать, разумеется, не нужно.
Re[3]: Не могу разобраться с указателем.
От:
Аноним
Дата:
18.07.12 14:18
Оценка:
Здравствуйте, BlackEric, Вы писали:
BE>Или можно BE>
HTA>>Эт чтобы не использовать AllocMem ? :-D BE>Я не знал про неё
А она в какому-то смысле основная.
Вроде как интерфейс менеджера памяти, который в Delphi как известно меняется когда надо, состоит из 4 функций.
Если не путаю. AllocMem, ReAllocMem, FreeMem, и GetMemBlockSize кажется
Здравствуйте, http://the_arioch.livejournal.com/, Вы писали:
HTA>>>Эт чтобы не использовать AllocMem ? :-D BE>>Я не знал про неё
HTL>А она в какому-то смысле основная.
HTL>Вроде как интерфейс менеджера памяти, который в Delphi как известно меняется когда надо, состоит из 4 функций. HTL>Если не путаю. AllocMem, ReAllocMem, FreeMem, и GetMemBlockSize кажется
Это смотря в какой версии.
В Delphi 7 нет.
В XE2 она выглядит совсем по другому и находится уже в System.
от менеджера памяти зависит GetMemory
function GetMemory(Size: NativeInt): Pointer; cdecl;
begin
Result := MemoryManager.GetMem(Size);
end;
var
pTempSurf:PSurface;
begin
New(pTempSurf); // создали, заняли память
FillChar(pTempSurf^, SizeOf(pTempSurf^), 0); // обнулили поля структуры (опционально)
TempSurf^.Data := nil; // пользуемся...
Dispose(pTempSurf); // попользовались, освободили памятьend;
Сто лет на Дельфи не писал, но должно быть как-то так.
Re[7]: Не могу разобраться с указателем.
От:
Аноним
Дата:
19.07.12 10:06
Оценка:
BE>Это смотря в какой версии. BE>В Delphi 7 нет.
Вот блин, а в Delphi 5 менялось...
Я ж тогда 2KB DLL делал, без выбивания стандартного heap'а этого бы не получилось.
Вообще предлагаю простоe правило — как только появились borlandmm.dll и midas.dll — не позже этого стали и переключаемый heap manager. возможно раньше.