New and getmem different

xiaoxiao2021-04-08  260

Today, I think of a problem: if you operate a string variable in a RECORD pointer, will String's memory space, causing memory leakage? The result is: Use new () allocation memory, automatically initialize the contents of Record, and automatically clear all allocated memory, including String or other moving arrays during Dispose. GetMem / FreeMem does not have this nature. In fact, New () is called GetMem and some initialization operations are performed. Code is as follows: type PMyRecord = ^ TMyRecord; TMyRecord = record I: Integer; S: string; V: Variant; end; {; $ DEFINE NEW} procedure TForm1.Button1Click (Sender: TObject); var R: PMyRecord; I: Integer Begin for i: = 1 to 1024 do begin {$ ifdef new} new (r); // correctly RS initialize SETLENGTH (RS, $ FFFF); Dispose (r); // Correctly release RS memory space {$ ELSE } GetMem (r, sizeof (tmyrecord)); RS: = ''; // Error setlength (RS, $ fff); FreeMem (r); {$ ENDIF} end;

============================================================================================================================================================================================================= =

Getmem is only responsible for allocating space, and it is not responsible for emptying the spatially allocated space. If you need to assign it, you can use allocmem, allocmem = getMem Fillchar

============================================================================================================================================================================================================= =

Oh, I made a mistake above, thinking that S = 0 will be wrong, so there is no FillChar, in fact, it will not. This can be measured correctly: (Remove the $ define new; remove, you can view the memory occupancy of two methods from the task manager) TYPE PMYRECORD = ^ TMYRECORD; TMYRECORD = Record i: integer; s: String; V: Variant; End; {; $ define new} process; var r: pmyrecord; var r: pmyrecord; i: integer; begin for i: = 1 to 1024 do begin {$ ifdef new} new (r) ; // correctly initialize SETLENGTH (RS, $ FFFF); Dispose (R); // Correctly release RS memory space {$ else} getmem (r, sizeof (tmyrecord)); Fillchar (R ^, Sizeof (TmyRecord) , # 0); SETLENGTH (RS, $ FFFF); FreeMem (R); // Does not release RS memory space !! {$ ENDIF} end; end; ============== =====================================

Yes, FreeMem does not release the content of automatic management of the survival period, because in FreeMem, it is consistent binary data, there is no meaning to say. But you can solve this problem with a Finalize (or FinalizeRecord) I estimate that Dispose is directly or indirectly called Finalize.

============================================================================================================================================================================================================= =

Oh, no estimate, the help clearly explain. In Delphi code, FreeMem destroys the variable referenced by P and returns its memory to the heap. If P does not point to memory in the heap, a runtime error occurs. If P points to a structure that includes long strings, variants, dynamic arrays , or interfaces, call Finalize before calling Freemem ...... Note:... It is preferable to use the New and Dispose procedures rather than GetMem and FreeMem When using New and Dispose, there is no need to explicitly call Finalize = =============================================================================================================================================================================================================

Guttier Wrote: Oh, no estimate, the help clearly explain. In Delphi code, FreeMem destroys the variable referenced by P and returns its memory to the heap. If P does not point to memory in the heap, a runtime error occurs. If P points to a structure that includes long strings, variants, dynamic arrays , or interfaces, call Finalize before calling Freemem ...... Note:. It is preferable to use the New and Dispose procedures rather than GetMem and FreeMem When using New and Dispose, there is no need to explicitly call Finalize..

I translated this in English. "In the Delphi code, FreeMem releases memory according to the pointer referenced by the variable, and returns the internal storage to the heap. If the pointer does not point to the memory address in the stack, a runtime error will occur. If the pointer points to a data structure, And there is a long string, a Variants, a dynamic array, or interface, then call finalize before using FreeMem, "Note: Use the New and Dispose processes to use GetMem and FreeMem. But when we use new and dispose, No need to display Finalize "is over. There is definitely inaccurate place. However, I have a problem, memory allocation Since New and Dispose are easier to use than getmem and FreeMem, then there is still necessary to use getMem, FreeMem, where do they use them? ============================================================================================================================================================================================================= = Memory Allocation Since New and Dispose are easier to use than getmem and FreeMem

"Easy to use" is usually only a relative concept. Here we discuss pointers to the structure, in which case New / Dispose is usually easy to use. However, they are limited, that is, the size of the space points to which must be able to determine during compilation, they know how much space needs to be assigned. For pointers to the structure, this value is the size of the structure, which is of course determined, so it can be used, and it can bring convenience. However, there are some situations, for example, you have only one Pointer type, this is a non-type pointer, you pass it to new, the compiler doesn't know what it points to, and I don't know how big it is pointing. I don't know how many spaces need to be assigned, it is not used at all, and it is not easy to use.

Is there any need to use getMem, FreeMem, use them in?

Of course, as mentioned earlier, relatively, New / Dispose operates more highly, we usually use them to operate the pointer to the structure, that is, the content that the pointer points to the content is known during compilation. structure. And when we need to do some memory space, if you want to handle the string, your pointer is that you only know or you can understand the memory space yourself, no compilation The clear data structure is corresponding to the period. At this time, you will use getMem / FreeMem. Therefore, the limitations of New / Dispose are actually large, or the applicable range is small, and GetMem / FreeMem gives us full freedom, and the range of trials is wider. Of course, which one is specifically selected, it depends on the actual situation.

转载请注明原文地址:https://www.9cbs.com/read-132670.html

New Post(0)