Board index » delphi » Pointers, Delphi's Internal Approach

Pointers, Delphi's Internal Approach

Can anybody explain or even better, point me to a resource, that
explains how delphi handles pointers.  It appears that I need to
pass the address of the first element in the case of arrays to get the
actual memory address.

From this I can only assume that Delphi has an internal table that the
pointer points to, this in turn points to the memory allocated against that
pointer. A kind of Microsoft VTable.

Its all so I can exactly understand what is being passed for examples such
as the READ method of a TMemoryStream (takes an untyped var).  Knowledge is
Power!

Thanks - MarkM

 

Re:Pointers, Delphi's Internal Approach


: "Mark Mamone" <mark.mam...@syntegra.bt.co.uk> wrote:

Quote
>Can anybody explain or even better, point me to a resource, that
>explains how delphi handles pointers.  

A pointer is a 4 byte location in memory that contains a memory
address. Period.

Quote
>Its all so I can exactly understand what is being passed for examples such
>as the READ method of a TMemoryStream (takes an untyped var).

You will want to know about TStream:

var
  x: Pointer;
  y: array[1..1000] of Byte;
begin
  GetMem(x, 1000);
  ...ReadBuffer(x^, 1000);
  ...ReadBuffer(y, 1000);

IOW, pointers in Delphi are like pointers in every other decent
programming language.

--
Stefan Hoffmeister    (http://www.econos.de/)
No private email, please, unless expressly invited.

Re:Pointers, Delphi's Internal Approach


On Mon, 1 Feb 1999 08:44:28 -0000, "Mark Mamone"

Quote
<mark.mam...@syntegra.bt.co.uk> wrote:
>Can anybody explain or even better, point me to a resource, that
>explains how delphi handles pointers.  It appears that I need to
>pass the address of the first element in the case of arrays to get the
>actual memory address.

Delphi handles pointers in the simplest possible way. If your mental
model involves extra, hidden levels of indirection, you misunderstand
them. Delphi doesn't do anything special or magic with pointers.

Quote
>From this I can only assume that Delphi has an internal table that the
>pointer points to, this in turn points to the memory allocated against that
>pointer. A kind of Microsoft VTable.

No.

Quote
>Its all so I can exactly understand what is being passed for examples such
>as the READ method of a TMemoryStream (takes an untyped var).  Knowledge is
>Power!

An untyped var argument requires a variable, not a pointer as an
argument.
--
Ray Lischner  (http://www.bardware.com)
co-author (with John Doyle) of Shakespeare for Dummies

Re:Pointers, Delphi's Internal Approach


What is happening here then

If I do the following

pPointer : Pointer;
pCharacter : PChar;

pCharacter := StrAlloc(100);
StrPCopy(pCharacter, '0123456789');
pPointer := Addr(pCharacter);

and I evalute them using CTRL+F7, I find the following

The pPointer points to the actual data.  The pCharacter holds an address
somewhere else.  If I get the Address of the [0] element, this is the same
address as the pPointer, if they are both pointers then Delphi obviously
treats TYPE POINTERS differently, it is this that I don't understand.

The READ method of memory stream takes a 'var Buffer'. If I pass a character
array address (not the first element address), it screws up the array.  This
is how the whole thing started.

I'm confuse, please help!

MarkM

Re:Pointers, Delphi's Internal Approach


 Hi "Mark Mamone" <mark.mam...@syntegra.bt.co.uk>;

 This is a public reply to your message posted:
 From group: comp.lang.pascal.delphi.misc;  on Tue, 2 Feb 1999 09:15:12 -0000
 Concerning "Re: Pointers, Delphi's Internal Approach";

 I am just an interested observer, with one question and one suggestion.

~ > What is happening here then
~ >
~ > If I do the following
~ >
~ > pPointer : Pointer;
~ > pCharacter : PChar;
~ >
~ > pCharacter := StrAlloc(100);
~ > StrPCopy(pCharacter, '0123456789');
~ > pPointer := Addr(pCharacter);
~ >
~ > and I evalute them using CTRL+F7, I find the following
~ >
~ >
~ > The pPointer points to the actual data.  The pCharacter holds an address
~ > somewhere else.  If I get the Address of the [0] element, this is the same
~ > address as the pPointer, if they are both pointers then Delphi obviously
~ > treats TYPE POINTERS differently, it is this that I don't understand.

    Does the address that pCharacter points to, contain the address of
    the [0] element?

~ > The READ method of memory stream takes a 'var Buffer'. If I pass a character
~ > array address (not the first element address), it screws up the array.  This
~ > is how the whole thing started.
~ >
~ > I'm confuse, please help!

  As I understand it (and maybe I don't), 'var Buffer' takes the
  dereferenced contents of an address and treats it like a pointer to
  the contents.  So you need to send the dereferenced contents to the
  var variable.  Personally I think this is absolutely insane ...

  Cordially;

--
 Friar Broccoli
 Robert Keith Elias  (Quebec, Qc, Canada)   Address: kel...@CLIC.NET
 Best programmer's & all purpose text editor: http://www.semware.com

 --------- I consider ALL arguments in support of my views ---------

Re:Pointers, Delphi's Internal Approach


Quote
Mark Mamone wrote:

> What is happening here then

> If I do the following

> pPointer : Pointer;
> pCharacter : PChar;

> pCharacter := StrAlloc(100);
> StrPCopy(pCharacter, '0123456789');
> pPointer := Addr(pCharacter);

> and I evalute them using CTRL+F7, I find the following

> The pPointer points to the actual data.  The pCharacter holds an address
> somewhere else.  If I get the Address of the [0] element, this is the same
> address as the pPointer, if they are both pointers then Delphi obviously
> treats TYPE POINTERS differently, it is this that I don't understand.

> The READ method of memory stream takes a 'var Buffer'. If I pass a character
> array address (not the first element address), it screws up the array.  This
> is how the whole thing started.

> I'm confuse, please help!

> MarkM

It's not pointers that are goofy here, but rather pchars/char
arrays/strings.  There is a lot of automatic converting/dereferencing
that goes on with these types so that they can be used interchangeably.
As far as the 'var buffer' goes, you should pass the array itself not
its address.  Var parameters take the address on their own. For example,
the following two procedures have the exact same values being passed

procedure DoStuffVar(var buffer);

...

procedure DoStuffAddr(buffer:pointer);

the difference is in how you use them.

var
  buffer:array[0..100] of char;
begin
  DoStuffVar(buffer);
  DoStuffAddr(@buffer);
end;

If you're using D4 dynamic arrays, they too are automatically
dereferenced.  In general, I think you're over analyzing the problem.
There ARE a lot of idiosyncracies lurking below the surface on what is a
pointer and what is not, but all the hidden pointer stuff is always
derefenced as needed so that they *behave* as if they weren't pointers.

Bob Lee

Re:Pointers, Delphi's Internal Approach


Quote
Robert Keith Elias wrote:
>   As I understand it (and maybe I don't), 'var Buffer' takes the
>   dereferenced contents of an address and treats it like a pointer to
>   the contents.  So you need to send the dereferenced contents to the
>   var variable.  Personally I think this is absolutely insane ...

I'm guessing that you and Mark are comming from a C/C++ background where
passing pointers around is a way of life.  

I believe that you and Mark are making this way too complex, essentially
because you know too much.  Forget about addresses and memory. One of
the strengths of Pascal is that you don't have to wade around in this
goop.  If you're using a lot of pointers (especially for characters or
arrays) then you're probably writing C code in pascal rather than pascal
code.    Think in terms of data and variables.

As for var params.

procedure One(var a:integer);

is equivalent to:

procedure Two(const a:^integer);

the difference is that within the routines you get to use 'a' rather
than 'a^' to fool with the value, and on calling the routine you can
pass 'a' rather than '@a'.  Thus, using var parameters reduces the
amount of referencing/dereferencing you have to do and so reduces the
clutter of the code.

Bob Lee

Re:Pointers, Delphi's Internal Approach


In article <796fmo$77...@pheidippides.axion.bt.co.uk>,
  "Mark Mamone" <mark.mam...@syntegra.bt.co.uk> wrote:

Quote
> What is happening here then

> If I do the following

> pPointer : Pointer;
> pCharacter : PChar;

> pCharacter := StrAlloc(100);
> StrPCopy(pCharacter, '0123456789');
> pPointer := Addr(pCharacter);

      The problem is that you're setting pPointer to the _address_
of pCharacter. pCharacter is a 4-byte variable; it holds the
address of that string. You don't want the location of the variable
holding the address, you (presumably?) want the address of the
string data itself. Ie you want the _contents_ of the pCharacter
variable:

pPointer := pCharacter;

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    

Re:Pointers, Delphi's Internal Approach


Im Artikel <36c5e93f.590892...@news.proaxis.com>, n...@junk.mail (Ray Lischner)
schreibt:

Quote
>An untyped var argument requires a variable, not a pointer as an
>argument.

But you can use somePointer^ instead. IMO similar rules apply to the level of
indirection in Delphi and C++. Therefore I'd appreciate any contributions, that
shed some light on the use of pointers in Delphi. It's not always clear, where
(implicit) pointers occur, that need allocation of according memory.

IMO both the original requestor and me know about pointers in C and on machine
level, but that knowledge doesn't help to find out, where and how pointers are
used in Delphi standard functions and data types. Just the buffers in I/O
functions need some explanations for Delphi novices.

DoDi

Re:Pointers, Delphi's Internal Approach


It was the Evaluate that confused me, if I enter the POINTER it shows the
address where the data is.  If I enter the PCHAR it shows me the address
that holds the pointer to where the data is.  I assumed that as they were
both pointers it should look the same but because PCHAR is a typed pointer,
it knows a little more about it and is intelligent in its answer.

I'd like to thank everybody for there help in me understanding this, and I
know it looks as though I'm making it WAY to complex BUT, I enjoy (call me
sad) looking at the internals of how the things works - I appreciate the
product more.  SO.....

I do come from a C++ background and to be honest the lack of thorough
understanding hasn't caused me any problems because I don't really passed
pointers to stuff around that much and when I do I let Delphis "Auto
Dereferencing" handling it for me, but..

How does Delphi handle the PCHAR, Array of bytes, Pointers etc INTERNALLY,
it must store information somewhere and this must incur an overhead.  Is
there information on this ?

MarkM

Re:Pointers, Delphi's Internal Approach


Quote
Mark Mamone wrote:
> How does Delphi handle the PCHAR, Array of bytes, Pointers etc INTERNALLY,
> it must store information somewhere and this must incur an overhead.  Is
> there information on this ?

strings and dynamic arrays are reference counted, everthing else is "you loose
it you leak it".  The reference count (as size info as well) are stored
negative to the pointer value.  Thus at p-4 you have a dword for the element
count, and p-8 you have a ref count.  (I'm not positive on the ref count
location).  In general, the heap manager does keep a list of allocated blocks
and their sizes.  That's why freemem doesn't need the size of the block any
more.

Bob Lee

Re:Pointers, Delphi's Internal Approach


In article <19990202230535.03036.00001...@ngol02.aol.com>,
  vb...@aol.com (VBDis) wrote:

Quote

> Im Artikel <36c5e93f.590892...@news.proaxis.com>, n...@junk.mail (Ray Lischner)
> schreibt:

> >An untyped var argument requires a variable, not a pointer as an
> >argument.

> But you can use somePointer^ instead.

       Right, except for the "but": somePointer^ is a variable.

Quote
> IMO similar rules apply to the level of
> indirection in Delphi and C++. Therefore I'd appreciate any contributions,
that
> shed some light on the use of pointers in Delphi. It's not always clear, where
> (implicit) pointers occur, that need allocation of according memory.

> IMO both the original requestor and me know about pointers in C and on machine
> level, but that knowledge doesn't help to find out, where and how pointers are
> used in Delphi standard functions and data types. Just the buffers in I/O
> functions need some explanations for Delphi novices.

        People have given plenty of general answers already - if you
want a more specific answer you might ask a specific question.

Quote
> DoDi

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    

Re:Pointers, Delphi's Internal Approach


Quote
>How does Delphi handle the PCHAR, Array of bytes, Pointers etc INTERNALLY,
>it must store information somewhere and this must incur an overhead.  Is
>there information on this ?

in D3, the StrAlloc help describes the mechanism.

Re:Pointers, Delphi's Internal Approach


: Robert Lee <rh...@nwu.edu> wrote:

Quote
>negative to the pointer value.  Thus at p-4 you have a dword for the element
>count, and p-8 you have a ref count.  (I'm not positive on the ref count
>location).  

100 per cent accurate.

--
Stefan Hoffmeister    (http://www.econos.de/)
No private email, please, unless expressly invited.

Re:Pointers, Delphi's Internal Approach


On 03 Feb 1999 04:05:35 GMT, vb...@aol.com (VBDis) wrote:

Quote
>...Therefore I'd appreciate any contributions, that
>shed some light on the use of pointers in Delphi. It's not always clear, where
>(implicit) pointers occur, that need allocation of according memory.

Syntactically, pointers are pretty much identical in Delphi and C++. The
most significant difference isn't related to pointers per se, but
objects, namely that all object references in Delphi are implicitly
pointers, but that isn't the case in C++.

Most of the problems Delphi users have with pointers are because they
want Delphi to behave like C or C++. For those of you who are not
familiar with C and C++, these languages use pointers to implements
arrays, strings, and VAR arguments. (C++ has references, but that's a
minor point.) Thus, any serious C and C++ programs uses pointers
heavily, and C and C++ programmers come to rely on pointers as the
solution to almost any programming problem.

That isn't true with Delphi.

Pascal in general and Delphi in particular avoid pointers in favor of
more controlled and more controllable approaches to programming. For
example, Pascal has real arrays. Delphi has real strings.

In C or C++, the ReadBuffer procedure would use a pointer argument, so
naive C and C++ programmers assume that Delphi uses a pointer argument.
It doesn't. Instead, Delphi uses an untyped VAR argument, which helps
prevent problems of invalid or nil pointers. Untyped VAR arguments--if
used correctly--are safer than pointer arguments.
--
Ray Lischner  (http://www.bardware.com)
co-author (with John Doyle) of Shakespeare for Dummies

Go to page: [1] [2]

Other Threads