Ptr Ptr Ptr .. variables

BlitzMax Forums/BlitzMax Programming/Ptr Ptr Ptr .. variables

plash(Posted 2009) [#1]
Is it possible to do this without using multiple local variables?
SuperStrict

Framework brl.blitz

Import brl.standardio

Local i:Int = 231
Local p3:Int Ptr Ptr Ptr, p2:Int Ptr Ptr, p1:Int Ptr

' Fail!
'p3 = Varptr(Varptr(Varptr(i)))

' Eh..
p1 = Varptr(i)
p2 = Varptr(p1)
p3 = Varptr(p2)

Print(p3[0][0][0])




Htbaa(Posted 2009) [#2]
What exactly are you trying to do? Make a pointer to a pointer?


plash(Posted 2009) [#3]
This example has no real-world use (to me), but when wrapping Mono I noticed the use of ** (double pointer) in some function prototypes, so I had to change parts of the wrapper to work with it.
Thus this question spawned.


Mahan(Posted 2009) [#4]

What exactly are you trying to do? Make a pointer to a pointer?



(Sorry for "big wall of text". This is a little historical background for the need for pointer-to-pointer types, and their development.)

In the C/C++ world pointers to pointers are very often used to make lists such as lists of strings and structs.

This is because with this layout you can easily mark the end of the list with a NULL-pointer at the end:

example:

level pointer to pointer to NULL-terminated string:

[ptr str#1][ptr str#2][NULL-address]

@ the ptr str#1 address:
[H][a][i][ ][I]['][m][ ][#][1][NULL-char]

@ the ptr str#2 address:
[H][a][i][ ][I]['][m][ ][#][2][NULL-char]


Thus in the C/C++ languages they made it very easy to define "levels of indirection" by the use of the pointer operator * (asterisk).

A pointer to pointer to char is simply declared like this:

char **c;

And since the language threats pointers very similar to arrays you can then write this code to access the first char of the first string in the list (If i remember correclty):

c[0][0]

As you can imagine this notation makes it very easy for any developer to make a mistake in the "levels of indirection" and then you often get an access violation, and C is very infamous for exactly this kind of errors as a usual cause of problems.

Most languages of today has therefore left the "naked pointer" approach and use "object references" instead, which in many cases actually are "naked pointers" but with the difference that the languages/compilers are much more strict in the way you are allowed to access that memory according to the type of the object that is referenced.


Htbaa(Posted 2009) [#5]
I know pointers to pointers are not uncommon in C++. I've used them myself as well.

Does BlitzMax actually support pointers-to-pointers? I suppose this fails:
p3 = Varptr(Varptr(Varptr(i)))
because the functions expect a variable and can't handle directly on the address.


Floyd(Posted 2009) [#6]
Does BlitzMax actually support pointers-to-pointers?


That's exactly what the original example does.

Varptr(Varptr(Varptr(i))) tries to get to i through intermediate pointers which don't exist.


plash(Posted 2009) [#7]
Varptr(Varptr(Varptr(i))) tries to get to i through intermediate pointers which don't exist.
So.. that isn't even possible in C?


Floyd(Posted 2009) [#8]
Let's try a simpler version with only two levels of pointer.

Framework brl.basic

Print

Global n:Int, p1:Int Ptr, p2:Int Ptr Ptr

n = 125
p1 = Varptr(n)
p2 = Varptr(p1)


Print " Address of n = " + Int(p1) 
Print "   Value of n = " + n
Print

Print p1[0]      ' same as n
Print p2[0][0]   ' also same a n

'p2 = Varptr( Varptr( n ) )



The commented out final line will not compile. But suppose it did and you could run the code. What would happen?

First, Varptr( n ) has to be evaluated. It will be an address, something like 4280000.
Next it tries to assign p2 = Varptr( 4280000 ), which is meaningless.

Even if this "succeeded" and assigned some value to p2 it would not be a valid address of anything allocated to your program.


plash(Posted 2009) [#9]
I see. So a pointer just has to be variableized (local, global, field, etc) to have something point to it.