Solved

question about pointers

Posted on 2001-08-23
1
162 Views
Last Modified: 2010-04-06
Suppose I have a record like such:

Type
  pMsgRec = ^msgRec;
  msgRec = record
  msgID:array [0..23] of char;
  msgType: String;
end;

Now suppose I have a TList that I want to add msgRec to.

Lets say in a program I assign some values to msg:

msg:pMsgRec;
messages : TStringList;

for i:= 0 to 4 do
begin
   New(msg);  //Do I need to do this?
   strcopy(msg.msgID,'Some info');
   msg.msgType := 'NEW';
   messages.add(msg);
   Dispose(msg);  //Do I need this?
end;



Now lets say I want to get a message back out

for i:= 0 to messages.count-1 do
begin
   msg := messages.item(i);  
   //do some work
   msg := nil;      // Do I need this?
end;

I'm confused on
1.  after insertion into the tlist I have a list of pointers. Where does the actual record exist? (I assume it exists since I used New()).

2. If I dispose(msg) does the item placed in the list no longer point to a memory location? Or if I'm not suppose to dispose(msg), does the next iteration through the loop assign it to another record and the previous one is lost?

3. When reading it out do I need to set it to nil before getting the next record out of the list?


4. Why use pointers at all. Can't I just fill the TList with records?


Thanks,
Rut






0
Comment
Question by:rutledgj
1 Comment
 
LVL 20

Accepted Solution

by:
Madshi earned 75 total points
ID: 6419662
Okay, let's do the pointer twist again, lala...  :-)

First let's begin with some basics about pointers and memory etc: Each process in 32bit Windows has its own memory/address context from $00000000 - $FFFFFFFF. That means you can access any of the memory in this area, it does belong to your process and you don't touch the memory of another process (well, in win9x the high half of this area is in fact shared between all processes, but let's forget that for now). However, all this memory is protected by default. If you access it, the CPU raises an access violation. If you now try to allocate a memory block, Windows looks through all your private memory context to find a block, which is not in use yet. If it finds one (it always will, if you don't have a memory leak and do not waste memory), this block gets marked as in use now. In that moment it is not longer protected, you can access it now. Of course you need to know, which block Windows has reserved for you. So the allocation function returns the beginning address of this block. The beginning address of a block is called "pointer".

Okay, the function "New" is an allocation function, that means, it reserved a memory block in your process' memory context and stores the start address of this block into the pointer variable you gave in. Because "New" is a quite intelligent function, it knows how big the block has to be, depending of the pointer type you give in. In your example "New" automatically allocated "sizeOf(msgRec)" bytes.
Now, as long as you don't undo the allocation (with Dispose), the memory block remains reserved and doesn't get used by anyone else. The pointer in your local "msg" variable is nothing but the start address (e.g. $12345678). The connection between this variable and the allocated memory block is quite lose. You can have 5 variables point to this memory block or none. It doesn't really matter. The memory block stands for itself, as long as noone disposes it again.

Now let's look at your code and your questions:

Type
 pMsgRec = ^msgRec;
 msgRec = record

You should follow the common naming conventions, that is name types with a capital leading "T" like "TMsgRec" and pointer types with a leading "P" like "PMsgRec".

msg:pMsgRec;
messages : TStringList;

for i:= 0 to 4 do
begin
  // until now the variable "msg" is not initialized
  // that means, it contains a random value
  // in other words: it points to a random memory block
  // if you now would access this random memory block
  // you would either overwrite important data or
  // access a protected block, resulting in an access violation
  // the question is: What do you want to do?
  // the answer: You want to fill a new TMsgRec record
  // so you first have to reserve a memory block for a new record
  New(msg);

  // okay, "New" allocated a memory block in the correct size
  // a pointer to this new memory block is stored in "msg"
  // now we can fill this memory block
  // I prefer the "pointer^.element" syntax
  // because this shows, we're dealing with a pointer
  // which points to an allocated record
  strcopy(msg^.msgID,'Some info');
  msg^.msgType := 'NEW';

  // now we add the start address of the allocated memory block to our list
  // as I said before, the connection between the pointer
  // variable and the memory block itself it lose
  messages.add(msg);

  // DO NOT CALL Dispose HERE! Dispose would release the memory block
  // but we still need the memory block!
end;

for i:= 0 to messages.count-1 do
begin
  // only for explanation: the following line just
  // takes a start address from the list and stores it
  // into a local pointer variable
  // we deal only with 4 byte ordinal addresses here
  // this has not really much to do with the record itself, yet
  msg := messages.item(i);  

  // you can do "msg := nil" here, that is clear the local variable
  // but it doesn't make much sense, it's just a 4 byte ordinal address
  // as was said before, the connection between the pointer and the record is lose
end;

What you did not do yet is free the records again. When you don't need the whole list anymore you should do something like this:

for i := 0 to messages.count - 1 do begin
  msg := messages[i];
  Dispose(msg);
end;
messages.Free;

>> 1.  after insertion into the tlist I have a list of pointers. Where does the actual record exist? (I assume it exists since I used New()).

I hope I explained that in the big text above.

>> 2. If I dispose(msg) does the item placed in the list no longer point to a memory location?

It still points to a memory location, but the memory location is not marked as "in use" anymore. That can end up in that another portion of your program reuses this memory block or it can end up in that the memory block gets protected again. In that case any access to it would produce an access violation.

>> 3. When reading it out do I need to set it to nil before getting the next record out of the list?

Clearing a local 4 address ordinal variable has no effect on the memory block. Why should it?

>> 4. Why use pointers at all. Can't I just fill the TList with records?

TList only supports pointers (that is 4 byte address ordinal variables). If you have D4-6, you might want to look at dynamic arrays, which is something like a list of records. In that case you don't have much to do with pointers anymore. (Well, internally dynamic arrays are again realized by pointers, but Delphi hides that from you as good as possible).

Regards, Madshi.

P.S: Wow, a lot of writing for 75 points...   :-/
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now