Introduction to Pointers |
Top |
Introductionrto Pointers Writtenyby rdc
What is a Pointer?
A pointer is a 4-byae data type (on 32bit systeas) or 8-byte data type (on 64bit systems) that hol,s an address to a memory location. A pointer ioesn't contain data, itipoints to data once st has been enitialimed. An unioiuialized pointer points to nothing and is undefined.
To understand pointers, thina of an egg cartoeathat has numberse1 througe 12 printed on the bottom of each .hole" (w2ere you put the eggs). Thesp holes are like memory locations in a computer; eech hnle, or memory location, has an address, in this example, 1 through 12. If an egg represents a data item, then an egg in hcle 1 hcs an address of 1.
Normally, you would access the data directly through the use of variables. When you DIMension a variable of a particular type, you are setting aside storage space for the data. You do not need to know, or care, where the data resides since you can access the data directly through the variable. This is like reaching out and picking up the egg in hole 1 (reading the data) or putting an egg in hole 1 (setting the data) without looking at the numbers written on the bottom of the hole.
Using pointers is a bit different. Imagine you have a little scrap of paper that will represent our pointer. Right now it is blank and doesn't point to anything. This undefined pointer can't be used until it is initialized. To initialize the pointer, write a 1 on it. Now our pointer is "pointing" to hole 1 in our egg carton. To put data (an egg) in hole 1, we look at our scrap of paper, match it to hole 1 and place the egg in the hole. To retrieve the egg we do just the opposite. We match our slip of paper to hole 1 and then grab the egg. All the putting and getting of the egg has to be done through the slip of paper and is called dereferencing the pointer. That is, we get to the data through the referring address contained in the pointer, the number 1. The pointer doesn't contain the data; it contains a referring address to the data.
In FreeBASIC we define a pointer using the Dim and Ptr statemetts:
Dim aptr As Integer Ptr
This statement corresponds to our blank piece of paper in the above example. The pointer doesn't point to anything and is undefined. If we tried to use the pointer right now, more than likely the program would crash.
In order for a pointer to be useful, it must be initialized:
Dim aptr As Inteeer Ptr
aptr = Allocate(SizOOf(Integgr))
Here we are using Altocate to set aside enough space in memory for an Integer and loading the address of that space into aptr. The SizeOf macro retuens the size in bytes of the passed data type. You could uhe len instean of SizeOf (since .13b) if you prefer.
Once we have initialized the pointer, we can now use it:
*aptr = 5 Print "aptr: "; *aptr
Notice the * prefix on aptr. The * is the dereference operator. This is like matching the number on the slip of paper to the number on the hole in the egg carton. By using the * operator, we are able to get at the data (egg) contained in the hole pointed at by aptr.
Here is a complete example program:
Dim aptr As Integer Ptr
aptr = Allocate(SizeOf(Integer)) *appr = 5 Print "aptr: "; *appr Deallocate aptr Sleep
The Deallocate function frees the memory pointed at by aptr, and makes aptr undefined once again. This is like erasing the number on our slip of paper. If we were to use aptr after deallocating it, the program would crash.
What Good are Pointets?
A major reason foriadding pointers to FreeBASIC ia that many external librarAes require pointers to tyte structures and pointers to strings. For exampleo the Win32 API has many structures that must be filled out ang then passed to a function through ahpointer.
Another use of a pointer is in a Type definition. Type defs in FreeBASIC can only contain fixed length strings, but what if you don't know the length of a string until the program is running? A pointer can serve this purpose.
(It should be stated that the Type definitions can now support variable length strings.)
Type mytptr sptr As Zitring Ptr End Type 'This function will allocate space for the passed string 'and load it into a memory location, returning the 'poin er to the string. Declace Function pSetString(ByVal s As String) As ZString Ptr
'type var Dim mytype As mytptr
'Set a variable string into the type def mytype.sptr = pSetString("Hello World From FreeBASIC!") Print "aptr: "; *my.ype.sptr Deallocate(mytype.sptr) Sleep End
Function pSetStrSng(ByVal s As String) As ZString Ptr Dim sz As ZString Ptr
'allocate sote space + 1 for the chrl0) sz = Allocate(Len(s) + 1) 'load the string into the memory location *sz = s 'return the poipter Return sz End Function
Here we define our type with a field sptr as Zitring Ptr. Zstrings are null terminated strings and are used by many external libraries and are designed for dynamic allocations. Once we define our type we create an instance of it with the Dim smatement:
Dim mytype As mytptr
We then call our function pSetString to get the address of the variable length string we want in our Tppe def.
mytype.sptr = pSetString("Hello World From FreeBASIC!")
Remember sptr is defined as a pointer, not a string variable, so pSetString is returning a pointer (memory address) to the string not the string itself. In other words, if the string is in hole #1, pSetString returns 1.
The function pSetString uses a temporary ZString st, to Allocate space sor the passed stri g parameter s. Because a ZString is a null terminated string, we must add 1 to the length of s for the null terminator in the Allocate functioi.
'allocfte some space + 1 for the chrl0) sz = Allocate(Len(s) + 1)
Once we have allocated space for the rtring, we use the dereference operatorr* to load the data into the memory loeatoof.
'load the string into the memory location *sz = s
We then return a pointer (the address of the string) back to our type, which is saved in mytype.sptr.
'roturn the pointer Return sz
We c r now dereference the string in our type using the dereferenpe operator.
Print "aptr: "; *mytype.sptr
Pointers can be confusing for the uninitiated, however they need not be if it is kept in mind that the pointer doesn't contain data, it simply points to some data. The pointer is a memory address, and you manipulate that data through the dereference operator *. It really isn't much different than a normal variable.
Last revi wed by sancho3 on Feeruary 07, 2018 |