Mailinglist Archive: opensuse-programming (128 mails)

< Previous Next >
Re: [suse-programming-e] Pointer strangeness
  • From: Derek Fountain <derekfountain@xxxxxxxxxxx>
  • Date: Tue, 8 Apr 2003 17:13:29 +0800
  • Message-id: <200304081713.29752.derekfountain@xxxxxxxxxxx>
> > A class definition is saved in the compiler's memory space during
> > compilation. Non-inline functions certainly do take up space in your
> > program's text segment (usually). class static variables are generally
> > allocated in the program's data segment. But the rest of the class is
> > simply a template for the compiler to use when the class is instatiated.
>
> Did you really mean 'compiler' here? I'm way out in unfamiliar territory
> here, but I would guess it is the OS kernel which uses this 'template' for
> instantiation. I'm trying to recall if the actual instructions of a
> function get placed on the stack. My guess is, instructions *do* get
> placed on the stack along with local variables.

I thought I'd stick my nose back into this thread. If I've missed too much to
say anything useful which hasn't been said before, just ignore me. :o)

Yes, he means compiler. Remember, the purpose of a compiler is to put together
a set of assembly language instructions, and make them into an executable
which the OS can run.

At *compile time* the compiler will look at your class definition and say
"that requires <n> bytes to store one object". It will also look at the
class' methods and say "this is the code which that class definition needs
available". It will therefore squirrel away one copy of all the method code.
Your guess in the quote above is wrong. :o) The instructions which make up a
function are stored once in the text segment. No need to make hundreds of
copies of a bit of code just 'cos you've got hundreds of objects
instantiated. They can share!

When the compiler finds a bit of code which instantiates an object, either on
the stack:

MyClass fred;

or on the heap:

MyClass* fred = new MyClass;

it needs to generate some code to do it. Remember: the compiler isn't doing
the actual instantiation; the compiler is generating the code which does it
when the OS runs the resultant program. So the psuedo-code generated will be:

allocate <n> bytes in the right place (i.e. on the stack or the heap)
call constructor subroutine with that memory block as a parameter

When the OS runs the program, a call to the system's memory allocation routine
(malloc or similar under Linux) will be made. That will be followed by a call
to the place in the program text segment where the constructor code has been
placed, basically saying "here's an empty block of memory big enough to hold
the object - fill it in!".

> the runtime behavior of the program. Nonetheless, the compiler has already
> done its job, and the kernel is the component actually doing the
> instantiation of classes as objects, and the memory allocation.

Not quite. The program which the compiler has generated, and which is running,
instantiates the objects. The program may very well use kernel or glibc
facilities to do this (because the compiler knows about those facilities and
generated code to use them), but that doesn't mean it's the kernel doing the
instantiation.

> However, from my observations, if I simply declare a variable of derived
> type, and never explicitly initialize that variable, the constructor of
> that class *is* invoked, and the member variables of that object *are*
> initialized.

You mean, if you say:

MyClass fred;

then the constructor for MyClass is called? Yes. And the member variables will
be set to 0s by default (see C++ spec), or anything that MyClass'
constructor, or any of the parent class' constructors sets them to
explicitly.

> By looking over the QT example code, the Trolls typically use pointers in
> such cases.

Yes, because QT is about widgets and widgets need to remain in place after the
code which creates them has been and gone. (e.g. Can't have all those buttons
which your toolbar created disappearing when the toolbar constructor is
completed and exits, can you?) So Qt creates the buttons on the heap:

QButton* button1 = new QButton( "Quit" );

and keeps the pointer (button1 in this case) around in the Toolbar class. When
the toolbar is destroyed, the destructor will ensure all the objects the
button pointers are pointing to are correctly destroyed.

If Qt did it on the stack:

QButton button1("Quit");

when the toolbar constructor exits, the stack memory allocated for that button
will be reclaimed and reused. That would be *bad*!

Qt, BTW, does all this pointer juggling for you: you create a toolbar and add
buttons to it. When you destroy your toolbar, Qt handles the tidying up of
all the buttons, etc. Gotta love Qt... :o)

--
"...our desktop is falling behind stability-wise and feature wise to KDE
...when I went to Mexico in December to the facility where we launched gnome,
they had all switched to KDE3." - Miguel de Icaza, March 2003


< Previous Next >
List Navigation
Follow Ups