### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: Pushing record to heap (Basic Question)  (Read 2213 times)

#### BrainChemistry

• Jr. Member
• Posts: 65
##### Pushing record to heap (Basic Question)
« on: June 08, 2018, 06:30:28 pm »
Hi there,

let's assume you have a large record.

Code: Pascal  [Select]
1. ExampleRecord = record
2.   entry1: Integer;
3.   entry2: AnotherRecord;
4.   entry3: array[0..1024] of Boolean;
5.   .
6.   .
7.
8. end;
9.

Well, in case of making the ExampleRecord part of a dyn. array, it would be completly pushed into the heap (is that true?). Let's assume I just need one instance of this record, it would be stored in the stack.

What can I do now to get it pushed to the heap?

If I do this

Code: Pascal  [Select]
1. New(@ExampleRecord);
2.

what follows for the elements of the array or the fields of AnotherRecord? Are the elements and the fields on the heap, too?

• Hero Member
• Posts: 9806
##### Re: Pushing record to heap (Basic Question)
« Reply #1 on: June 08, 2018, 06:46:13 pm »
Hi there,

let's assume you have a large record.

Code: Pascal  [Select]
1. ExampleRecord = record
2.   entry1: Integer;
3.   entry2: AnotherRecord;
4.   entry3: array[0..1024] of Boolean;
5.   .
6.   .
7.
8. end;
9.

Well, in case of making the ExampleRecord part of a dyn. array, it would be completly pushed into the heap (is that true?). Let's assume I just need one instance of this record, it would be stored in the stack.
If it is a global record, YES, heap, if it is local to a procedure or function, NO, stack!
Quote
What can I do now to get it pushed to the heap?
It isn't!
Quote
If I do this

Code: Pascal  [Select]
1. New(@ExampleRecord);
2.

what follows for the elements of the array or the fields of AnotherRecord? Are the elements and the fields on the heap, too?
You completely misunderstand what's happening. But IF it is a global record or a local pointer to record then yes.. it is on the heap. But if it is declared on the stack the members are also on the stack, unless declared as a pointer to record and new(0 and Dispose() Then it is on the heap. (And inaccessible when declared as local and you forgot to call dispose: memory leak).
When you use the record locally (not the pointer) it will be free'd automatically because it is on the stack (in full) if you use new() and Dispose() locally only the pointer disappears from the stack and you have a memory leak if you do not call dispose.

Note if your record contains members of a managed type, these are always on the heap (Like AnsiStrings, classes and interfaces). Even if the record is on the stack.
« Last Edit: June 08, 2018, 06:54:39 pm by Thaddy »
I am more like donkey than shrek

#### BrainChemistry

• Jr. Member
• Posts: 65
##### Re: Pushing record to heap (Basic Question)
« Reply #2 on: June 09, 2018, 02:35:41 am »

Well, in case of making the ExampleRecord part of a dyn. array, it would be completly pushed into the heap (is that true?). Let's assume I just need one instance of this record, it would be stored in the stack.
If it is a global record, YES, heap, if it is local to a procedure or function, NO, stack!

If I do this

Code: Pascal  [Select]
1. New(@ExampleRecord);
2.

what follows for the elements of the array or the fields of AnotherRecord? Are the elements and the fields on the heap, too?
You completely misunderstand what's happening. But IF it is a global record or a local pointer to record then yes.. it is on the heap. But if it is declared on the stack the members are also on the stack, unless declared as a pointer to record and new(0 and Dispose() Then it is on the heap. (And inaccessible when declared as local and you forgot to call dispose: memory leak).
When you use the record locally (not the pointer) it will be free'd automatically because it is on the stack (in full) if you use new() and Dispose() locally only the pointer disappears from the stack and you have a memory leak if you do not call dispose.

Note if your record contains members of a managed type, these are always on the heap (Like AnsiStrings, classes and interfaces). Even if the record is on the stack.
I messed up the second code snippet since I was in a hurry on writing, sorry for that inconvenience. It should better have read like this:
Code: Pascal  [Select]
1. PExampleRecord = ^ExampleRecord // type sec.
2. .
3. .
4. New(PExampleRecord); // begin..end. sec.
5.

Well, about your description I try to translate it into code and I'd appreciate to learn if my assumptions about the used memory is correct.
Code: Pascal  [Select]
1. //global var sec.
2. var
3.   MyGlobalRecord: ExampleRecord;
4.
5. .
6. .
7. // procedure declaration
8. procedure AProcedure;
9. var
10.   MyLocalRecord: ExampleRecord;
11.   PMyLocalRecord: ^ExampleRecord;
12. .
13. .
14. New(PMyLocalRecord); // the record and all its members are on the heap
15. .
16. .
17. MyLocalRecord := AnotherRecord; // MyLocalRecord and all its members are on the stack
18.
19. // begin..end. block
20. begin
21.   MyGlobalRecord := AnotherRecord; // MyGlobalRecord and all its members are on the heap
22. end.
23.
« Last Edit: June 09, 2018, 02:39:32 am by BrainChemistry »

• Hero Member
• Posts: 9806
##### Re: Pushing record to heap (Basic Question)
« Reply #3 on: June 09, 2018, 09:01:01 am »
Here's a summary program.
Use the debugger to see the different behavior.
Code: Pascal  [Select]
1. program records;
2. // example of record behavior
3. // assumes record without members that need finalization
4. {\$mode objfpc}
5. type
6.   PMyRecord = ^TMyRecord;
7.   TmyRecord = record
8.   a,b:integer;
9.   c:string[255];
10.   end;
11.
12. procedure Localrecord;
13. var a:TMyRecord;
14. begin
15.   //stack allocated;
16.   a.a := 100;
17.   a.b := 200;
18.   a.c := 'Test Local';
19.   writeln(a.c);
20. end;
21. procedure LocalDynamicRecord;
22. var a:PMyRecord;
23. begin
24.   // Pointer on stack record on heap;
25.   New(a);
26.   // code
27.   a^.a := 100;
28.   a^.b := 200;
29.   a^.c := 'Test Local Dynamic';
30.   writeln(a^.c);
31.   Dispose(a);
32. end;
33.
34. var
35.   //heap allocated, no clean up necessary
36.   GlobalRecord:TMyrecord;
37.   //dynamically heap allocated, needs clean up.
38.   GlobalDynamicRecord:PMyRecord;
39. begin
40.   GlobalRecord.a := 100;
41.   GlobalRecord.b := 200;
42.   GlobalRecord.c := 'Test Global';
43.   writeln(GlobalRecord.c);
44.   New(GlobalDynamicRecord);
45.   // code
46.   GlobalDynamicRecord^.a := 100;
47.   GlobalDynamicRecord^.b := 200;
48.   GlobalDynamicRecord^.c := 'Test Global Dynamic';
49.   writeln(GlobalDynamicRecord^.c);
50.   Dispose(GlobalDynamicRecord);
51.   LocalRecord;
52.   LocalDynamicRecord;
53. end.

« Last Edit: June 09, 2018, 09:07:10 am by Thaddy »
I am more like donkey than shrek

#### BrainChemistry

• Jr. Member
• Posts: 65
##### Re: Pushing record to heap (Basic Question)
« Reply #4 on: June 09, 2018, 02:22:58 pm »
Thanks for your effort, it helped alot!