C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Heap-Verständnisfrage
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Moritz Ulrich
Guest





PostPosted: Fri Apr 06, 2007 1:28 am    Post subject: Heap-Verständnisfrage Reply with quote



Ich habe da mal eine kleine Frage zu Instanzen einer Klasse auf dem Heap.

Ein Beispiel wird wohl das passenste sein, von daher:

class foo
{
public:
foo():
~foo()
private:
int m_irgendwas[30][20];
};

Ich lasse die Implentierungen mal weg, aber nun zu meiner Frage:

Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle, liegt dann das Mehrdimensionale Array auch auf dem
Heap?


Gruß
Moritz
Back to top
Florian Weimer
Guest





PostPosted: Fri Apr 06, 2007 3:55 pm    Post subject: Re: Heap-Verständnisfrage Reply with quote



* Moritz Ulrich:

Quote:
Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle, liegt dann das Mehrdimensionale Array auch auf
dem Heap?

Die erste ebene von Pointern liegt auf dem Heap und ist
uninitialisiert. Typischerweise mußt Du die zweite Ebene von Hand
füllen, wodurch die entsprechenden Objekte ebenfalls auf dem Heap
landen.
Back to top
Torsten Robitzki
Guest





PostPosted: Fri Apr 06, 2007 4:18 pm    Post subject: Re: Heap-Verständnisfrage Reply with quote



Moritz Ulrich wrote:

Quote:
Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle, liegt dann das Mehrdimensionale Array auch auf
dem Heap?

Kurze Antwort: Ja. Lange Antwort: Es gibt in C++ gar keinen Heap, es
gibt eine free store.

mfg Torsten
Back to top
Marcel Müller
Guest





PostPosted: Fri Apr 06, 2007 4:32 pm    Post subject: Re: Heap-Verständnisfrage Reply with quote

Moritz Ulrich wrote:
Quote:
Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle, liegt dann das Mehrdimensionale Array auch auf
dem Heap?

Ja.
Alle Attribute von Klassen/Strukturen und ihren Basisklassen liegen
immer in einem Speicherblock.

Heap-Objekte können eigentlich nicht sinnvoll referenzierte Komponenten
auf dem Stack haben, da das üblicherweise Probleme mit der Lebensdauer
gibt. Andersherum geht natürlich schon.
Es gibt aber auch Ausnahmen von der Regel, z.B. für Semaphoren, die z.B.
eine Liste von wartenden Threads über Objekte auf dem Stack halten.


Marcel
Back to top
Moritz Ulrich
Guest





PostPosted: Fri Apr 06, 2007 5:59 pm    Post subject: Re: Heap-Verständnisfrage Reply with quote

Am 05.04.2007, 22:28 Uhr, schrieb Moritz Ulrich
<thekenny123 (AT) googlemail (DOT) com>:

Quote:
Ich habe da mal eine kleine Frage zu Instanzen einer Klasse auf dem Heap.

Ein Beispiel wird wohl das passenste sein, von daher:

class foo
{
public:
foo():
~foo()
private:
int m_irgendwas[30][20];
};

Ich lasse die Implentierungen mal weg, aber nun zu meiner Frage:

Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle, liegt dann das Mehrdimensionale Array auch auf
dem Heap?


Gruß
Moritz


Ok, eigentlich ist das eine sehr dumme Frage, also antworte ich mir
selber^^
Eigentlich ist das Array die einzige Sache der Klasse, die wirklich
Speicher brauch. Die Methoden liegen selber irgendwo im Speicher, sind
aber nur irgendwelcher Bytecode. Das Array sind die einzigen wirklichen
"Daten" die verändert werden etc.
Sehe ich das richtig?
Back to top
Thomas Maeder
Guest





PostPosted: Fri Apr 06, 2007 7:05 pm    Post subject: Re: Heap-Verständnisfrage Reply with quote

"Moritz Ulrich" <thekenny123 (AT) googlemail (DOT) com> writes:

Quote:
Ich habe da mal eine kleine Frage zu Instanzen einer Klasse auf dem
Heap.

"Heap" ist im Kontext von C++ (oder C) kein definierter Begriff. Du
meinst Objekte mit dynamischer Lebensdauer ("storage duration"). Wo
eine C++-Implementation die anlegt, ist ihre Sache, solange sie sich
an gewisse Vorgaben hält.


Quote:
Ein Beispiel wird wohl das passenste sein, von daher:

class foo
{
public:
foo():
~foo()
private:
int m_irgendwas[30][20];
};

Ich lasse die Implentierungen mal weg, aber nun zu meiner Frage:

Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle,

Tust Du nicht. Du erzeugst dynamisch *eine Instanz* der Klasse.


Quote:
liegt dann das Mehrdimensionale Array auch auf dem Heap?

Eben, das ist implementationsabhängig.

Du darfst aber davon ausgehen, dass der Speicherbereich, den
*irgendwas belegt, zusammenhängt, die Grösse 20*30*sizeof(int) (plus
evtl. ein paar zerquetschte) hat und das Array m_irgendwas beinhaltet.
Back to top
Rolf Magnus
Guest





PostPosted: Sat Apr 07, 2007 5:45 pm    Post subject: Re: Heap-Verständnisfrage Reply with quote

Torsten Robitzki wrote:

Quote:
Moritz Ulrich wrote:

Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle, liegt dann das Mehrdimensionale Array auch auf
dem Heap?

Kurze Antwort: Ja. Lange Antwort: Es gibt in C++ gar keinen Heap, es
gibt eine free store.

Doch, gibt's schon, ist aber was ganz anderes.
Back to top
Thomas Mang
Guest





PostPosted: Tue Apr 10, 2007 1:01 pm    Post subject: Re: Heap-Verständnisfrage Reply with quote

Thomas Maeder wrote:
Quote:
"Moritz Ulrich" <thekenny123 (AT) googlemail (DOT) com> writes:

Ich habe da mal eine kleine Frage zu Instanzen einer Klasse auf dem
Heap.

"Heap" ist im Kontext von C++ (oder C) kein definierter Begriff. Du
meinst Objekte mit dynamischer Lebensdauer ("storage duration"). Wo
eine C++-Implementation die anlegt, ist ihre Sache, solange sie sich
an gewisse Vorgaben hält.


Genau.

Quote:


Ein Beispiel wird wohl das passenste sein, von daher:

class foo
{
public:
foo():
~foo()
private:
int m_irgendwas[30][20];
};

Ich lasse die Implentierungen mal weg, aber nun zu meiner Frage:

Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle,

Tust Du nicht. Du erzeugst dynamisch *eine Instanz* der Klasse.


liegt dann das Mehrdimensionale Array auch auf dem Heap?

Eben, das ist implementationsabhängig.

Du darfst aber davon ausgehen, dass der Speicherbereich, den
*irgendwas belegt, zusammenhängt, die Grösse 20*30*sizeof(int) (plus
evtl. ein paar zerquetschte) hat und das Array m_irgendwas beinhaltet.


Ich habe zwar jetzt eine längere C++ - Pause hinter mir, aber meine
Erinnerung sagt mir:
Nein. foo ist nicht POD, also muss der Specherbereich nicht
zusammenhängen. Der Rest des Satzes ist wohl wortauslegungssache Wink,
wenn Du mit Grösse den Wert des sizeof() - Operators meinst sage ich
ebenfalls nein - der bezieht sich auf die object-representation des
Objektes (zum Unterschied zur value-representation - und wie die dann
implementiert ist schreibt sowieso niemand vor).

Es ist legal, die klasse foo als Implementation nur mit einem Zeiger auf
z.b. das array auszustatten, dass dann irgendwo liegen kann. Dann wäre
sizeof(foo) == sizeof(internerPointer)
Back to top
Rolf Magnus
Guest





PostPosted: Wed Apr 11, 2007 10:13 am    Post subject: Re: Heap-Verständnisfrage Reply with quote

Thomas Mang wrote:

Quote:
Thomas Maeder wrote:
"Moritz Ulrich" <thekenny123 (AT) googlemail (DOT) com> writes:

Ich habe da mal eine kleine Frage zu Instanzen einer Klasse auf dem
Heap.

"Heap" ist im Kontext von C++ (oder C) kein definierter Begriff.

Doch, er ist definiert, aber anders. Aus der C++-Norm:

"A heap is a particular organization of elements in a range between two
random access iterators [a, b).
Its two key properties are:
(1) *a is the largest element in the range and
(2) *a may be removed by pop_heap(), or a new element added by push_heap(),
in O(log N) time."

Quote:
Ein Beispiel wird wohl das passenste sein, von daher:

class foo
{
public:
foo():
~foo()
private:
int m_irgendwas[30][20];
};

Ich lasse die Implentierungen mal weg, aber nun zu meiner Frage:

Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle,

Tust Du nicht. Du erzeugst dynamisch *eine Instanz* der Klasse.


liegt dann das Mehrdimensionale Array auch auf dem Heap?

Eben, das ist implementationsabhängig.

Du darfst aber davon ausgehen, dass der Speicherbereich, den
*irgendwas belegt, zusammenhängt, die Grösse 20*30*sizeof(int) (plus
evtl. ein paar zerquetschte) hat und das Array m_irgendwas beinhaltet.


Ich habe zwar jetzt eine längere C++ - Pause hinter mir, aber meine
Erinnerung sagt mir:
Nein. foo ist nicht POD, also muss der Specherbereich nicht
zusammenhängen. Der Rest des Satzes ist wohl wortauslegungssache Wink,
wenn Du mit Grösse den Wert des sizeof() - Operators meinst sage ich
ebenfalls nein - der bezieht sich auf die object-representation des
Objektes (zum Unterschied zur value-representation - und wie die dann
implementiert ist schreibt sowieso niemand vor).

Zu den Begriffen meint die C++-Norm:

"The object representation of an object of type T is the sequence of N
unsigned char objects taken up by the object of type T, where N equals
sizeof(T). The value representation of an object is the set of bits
that hold the value of type T."

Das scheint zu bedeuten, daß mit "object representation" der Speicher
gemeint ist, den das Objekt belegt, während die "value representation"
einfach die Daten sind, die dann in diesem Speicher liegen.

Quote:
Es ist legal, die klasse foo als Implementation nur mit einem Zeiger auf
z.b. das array auszustatten, dass dann irgendwo liegen kann.

Kannst du das irgendwie belegen?
Back to top
James Kanze
Guest





PostPosted: Wed Apr 11, 2007 8:28 pm    Post subject: Re: Heap-Verständnisfrage Reply with quote

On Apr 10, 10:01 am, Thomas Mang <noth...@provided.com> wrote:
Quote:
Thomas Maeder wrote:
"Moritz Ulrich" <thekenny...@googlemail.com> writes:
[...]
Ein Beispiel wird wohl das passenste sein, von daher:

class foo
{
public:
foo():
~foo()
private:
int m_irgendwas[30][20];
};

Ich lasse die Implentierungen mal weg, aber nun zu meiner Frage:

Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle,

Tust Du nicht. Du erzeugst dynamisch *eine Instanz* der Klasse.

liegt dann das Mehrdimensionale Array auch auf dem Heap?

Eben, das ist implementationsabhängig.

Du darfst aber davon ausgehen, dass der Speicherbereich, den
*irgendwas belegt, zusammenhängt, die Grösse 20*30*sizeof(int) (plus
evtl. ein paar zerquetschte) hat und das Array m_irgendwas beinhaltet.

Ich habe zwar jetzt eine längere C++ - Pause hinter mir, aber meine
Erinnerung sagt mir:
Nein. foo ist nicht POD, also muss der Specherbereich nicht
zusammenhängen.

Jein. Es kann in Prinzip vorkommen, dass es löcher drin gibt,
aber... sizeof(foo) muss eine Konstante sein, und es muss bei
new foo genau einen Aufruf operator new geben, mit als Parameter
sizeof(foo). Damit sind die Möglichkeiten etwas begrenzt.
Zeigerarithmetik muss auch funktionnieren, wenn man einen Feld
von foo hat; ich glaube sogar, dass angegeben foo* p, (char*)p
<= (char*)p->m_irgendwas < (char*)(p + 1) garantiert ist. (Ich
bin aber nicht sicher darüber.)

Quote:
Der Rest des Satzes ist wohl wortauslegungssache Wink,
wenn Du mit Grösse den Wert des sizeof() - Operators meinst sage ich
ebenfalls nein - der bezieht sich auf die object-representation des
Objektes (zum Unterschied zur value-representation - und wie die dann
implementiert ist schreibt sowieso niemand vor).

Es ist legal, die klasse foo als Implementation nur mit einem Zeiger auf
z.b. das array auszustatten, dass dann irgendwo liegen kann. Dann wäre
sizeof(foo) == sizeof(internerPointer)

Ich glaube nicht. Gehen wir davon aus, dass ich operator new
ersetzt habe. Damit sind Aufrufe von ihm "sichtbares Verhalten".
Also: wenn man "new foo" schreibt, muss operator new genau
einmal aufgerufen werden, weder mehr noch weniger. Angegeben, er
ermittelt einen Zeiger zurück; nachdem darf keine Ausnahme
auftreten, es sei dann, ich habe es im Constructor explizit
geschrieben. Woher dann soll anderer Speicher kommen?

--
James Kanze (GABI Software) email:james.kanze (AT) gmail (DOT) com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
Thomas Mang
Guest





PostPosted: Thu Apr 12, 2007 4:06 am    Post subject: Re: Heap-Verständnisfrage Reply with quote

Rolf Magnus wrote:
Quote:
Thomas Mang wrote:


Ein Beispiel wird wohl das passenste sein, von daher:

class foo
{
public:
foo():
~foo()
private:
int m_irgendwas[30][20];
};

Ich lasse die Implentierungen mal weg, aber nun zu meiner Frage:

Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle,
Tust Du nicht. Du erzeugst dynamisch *eine Instanz* der Klasse.


liegt dann das Mehrdimensionale Array auch auf dem Heap?
Eben, das ist implementationsabhängig.

Du darfst aber davon ausgehen, dass der Speicherbereich, den
*irgendwas belegt, zusammenhängt, die Grösse 20*30*sizeof(int) (plus
evtl. ein paar zerquetschte) hat und das Array m_irgendwas beinhaltet.

Ich habe zwar jetzt eine längere C++ - Pause hinter mir, aber meine
Erinnerung sagt mir:
Nein. foo ist nicht POD, also muss der Specherbereich nicht
zusammenhängen. Der Rest des Satzes ist wohl wortauslegungssache Wink,
wenn Du mit Grösse den Wert des sizeof() - Operators meinst sage ich
ebenfalls nein - der bezieht sich auf die object-representation des
Objektes (zum Unterschied zur value-representation - und wie die dann
implementiert ist schreibt sowieso niemand vor).

Zu den Begriffen meint die C++-Norm:

"The object representation of an object of type T is the sequence of N
unsigned char objects taken up by the object of type T, where N equals
sizeof(T). The value representation of an object is the set of bits
that hold the value of type T."

Das scheint zu bedeuten, daß mit "object representation" der Speicher
gemeint ist, den das Objekt belegt, während die "value representation"
einfach die Daten sind, die dann in diesem Speicher liegen.


Das magische Wort in Deinem Satz lautet "in *diesem* Speicher liegen".

Für PODs lese ich die Norm so dass das gegeben sein muss (3.9/4 nächster
Satz):

"For POD types, the value representation is a set of bits in the object
representation that determines a value, which is one discrete element of
an implementation-defined set of values."

Für nicht-POD steht nichts entsprechendes da.


Quote:

Es ist legal, die klasse foo als Implementation nur mit einem Zeiger auf
z.b. das array auszustatten, dass dann irgendwo liegen kann.

Kannst du das irgendwie belegen?


Meiner Meinung nach musst Du das Gegenteil belegen, nämlich dass die
value-representation immer in der object-representation liegen muss. Ich
kenne keinen Paragraphen der dies verlangt, deshalb ist mein
Umkehrschluss eben dass es nicht so sein muss.

Praktisch gesehen ... unterschreibe ich mit gutem Gewissen dass es so
sein wird. Ich glaube aber nicht dass es explizit verlangt wird.

Thomas
Back to top
Thomas Mang
Guest





PostPosted: Thu Apr 12, 2007 4:48 am    Post subject: Re: Heap-Verständnisfrage Reply with quote

James Kanze wrote:
Quote:
On Apr 10, 10:01 am, Thomas Mang <noth...@provided.com> wrote:
Thomas Maeder wrote:
"Moritz Ulrich" <thekenny...@googlemail.com> writes:
[...]
Ein Beispiel wird wohl das passenste sein, von daher:

class foo
{
public:
foo():
~foo()
private:
int m_irgendwas[30][20];
};

Ich lasse die Implentierungen mal weg, aber nun zu meiner Frage:

Wenn ich diese Klasse z.b. mit

foo *irgendwas = new foo();

auf dem Heap erstelle,

Tust Du nicht. Du erzeugst dynamisch *eine Instanz* der Klasse.

liegt dann das Mehrdimensionale Array auch auf dem Heap?

Eben, das ist implementationsabhängig.

Du darfst aber davon ausgehen, dass der Speicherbereich, den
*irgendwas belegt, zusammenhängt, die Grösse 20*30*sizeof(int) (plus
evtl. ein paar zerquetschte) hat und das Array m_irgendwas beinhaltet.

Ich habe zwar jetzt eine längere C++ - Pause hinter mir, aber meine
Erinnerung sagt mir:
Nein. foo ist nicht POD, also muss der Specherbereich nicht
zusammenhängen.

Jein. Es kann in Prinzip vorkommen, dass es löcher drin gibt,
aber... sizeof(foo) muss eine Konstante sein, und es muss bei
new foo genau einen Aufruf operator new geben, mit als Parameter
sizeof(foo). Damit sind die Möglichkeiten etwas begrenzt.
Zeigerarithmetik muss auch funktionnieren, wenn man einen Feld
von foo hat; ich glaube sogar, dass angegeben foo* p, (char*)p
= (char*)p->m_irgendwas < (char*)(p + 1) garantiert ist. (Ich
bin aber nicht sicher darüber.)

Im ersten Teil stimme ich mit Dir überein. Was den Zeigervergleich
angeht bin ich allgemein auch ziemlich unsicher (ich kann den
Paragraphen mit den Garantien für Speicheraddressen im Moment überhaupt
nicht finden).


Quote:

Der Rest des Satzes ist wohl wortauslegungssache Wink,
wenn Du mit Grösse den Wert des sizeof() - Operators meinst sage ich
ebenfalls nein - der bezieht sich auf die object-representation des
Objektes (zum Unterschied zur value-representation - und wie die dann
implementiert ist schreibt sowieso niemand vor).

Es ist legal, die klasse foo als Implementation nur mit einem Zeiger auf
z.b. das array auszustatten, dass dann irgendwo liegen kann. Dann wäre
sizeof(foo) == sizeof(internerPointer)

Ich glaube nicht. Gehen wir davon aus, dass ich operator new
ersetzt habe. Damit sind Aufrufe von ihm "sichtbares Verhalten".
Also: wenn man "new foo" schreibt, muss operator new genau
einmal aufgerufen werden, weder mehr noch weniger. Angegeben, er
ermittelt einen Zeiger zurück; nachdem darf keine Ausnahme
auftreten, es sei dann, ich habe es im Constructor explizit
geschrieben. Woher dann soll anderer Speicher kommen?

Das ist das Problem des Compilers Wink
Nein, im Ernst, praktisch gesehen ist das selbstverständlich ein sehr
sehr guter Grund (nebst anderen) dass die value-representation immer ein
Teil der object representation ist. Nur glaube ich nicht dass es
verpflichtet ist - auch nicht implizit über Umwege.

Rein theoretisch ist es ja möglich dass im gesamten Programm nur eine
z.B. Handvoll foo-s per new-expression erzeugt werden, und der Compiler
dass weiß. Wenn er garantieren kann dass für jede Instanz genug Speicher
für das array irgendwo zur Verfügung steht (z.B. im selben
Speicherbereich wo static - objects angelegt werden), sollte ja alles in
Ordnung sein. Genauso wäre es möglich, dass er das object-layout von foo
abhängig davon macht ob operator new überschrieben wurde oder nicht.

Selbstverständlich sind das alles Dinge die ich von keinem realen
Compiler erwarte (das hätte ich vielleicht von Anfang an klarer
schreiben sollen). Aber sind sie deshalb per se ausgeschlossen?

Ich kann mich an eine heiße Diskussion über object-layout und ähnliches
erinnern:
http://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/thread/4a0661ad428ab619/
Da ging es teilweise zwar um contiguous und nicht-contiguous objects,
aber vielleicht ist ja was besonders nützliches dabei.

Thomas
Back to top
Thomas Mang
Guest





PostPosted: Fri Apr 13, 2007 12:51 am    Post subject: Re: Heap-Verständnisfrage Reply with quote

Thomas Mang wrote:
Quote:

Selbstverständlich sind das alles Dinge die ich von keinem realen
Compiler erwarte (das hätte ich vielleicht von Anfang an klarer
schreiben sollen). Aber sind sie deshalb per se ausgeschlossen?

Ich kann mich an eine heiße Diskussion über object-layout und ähnliches
erinnern:
http://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/thread/4a0661ad428ab619/


Es war wirklich in dieser Diskussion, aber wegen der Länge letzter
ziemlich gut versteckt:

Die Idee mit dem Zeiger statt Datenmember wird von David Abrahams hier
aufgeworfen:
http://tinyurl.com/28djes

und die Antwort wegen exception kommt hier:
http://tinyurl.com/yuoknz

Also greift wieder mal die
"jedes-Programm-ist-Undef.-Verhalten-weil-wenn-es-sonst-nichts-ist-dann-sind-eben-ressourcen-limiert"
Regel.

Zu diesen Punkten ist dann kein weiterer Widerspruck hinzugekommen.


Dazwischen eist auch ein netter, langer Exkurs über contiguous, region,
subojects, Englisch-Lesen etc. Und dass man die Norm stets im Sinne der
Erfinder lesen muss, auch wenn die sich vielleicht nicht so klar
ausgedrückt haben...



Nach all dem sage ich:
Für jeden non-POD-typ darf man weder damit rechnen, dass die
Objekt-repräsentation in einem zusammenhängenden Stück Speicher liegt,
noch dass sizeof(someClass) mindestens die Summe von sizeof aller
Daten-member ist - wenngleich diese value-bits selbstverständlich
irgendwo liegen müssen [es sei denn sie werden aufgrund von as-if gar
nicht gebraucht...]


Thomas
Back to top
James Kanze
Guest





PostPosted: Fri Apr 13, 2007 6:35 pm    Post subject: Re: Heap-Verständnisfrage Reply with quote

On Apr 12, 1:48 am, Thomas Mang <noth...@provided.com> wrote:
Quote:
James Kanze wrote:
On Apr 10, 10:01 am, Thomas Mang <noth...@provided.com> wrote:
Thomas Maeder wrote:

Jein. Es kann in Prinzip vorkommen, dass es löcher drin gibt,
aber... sizeof(foo) muss eine Konstante sein, und es muss bei
new foo genau einen Aufruf operator new geben, mit als Parameter
sizeof(foo). Damit sind die Möglichkeiten etwas begrenzt.
Zeigerarithmetik muss auch funktionnieren, wenn man einen Feld
von foo hat; ich glaube sogar, dass angegeben foo* p, (char*)p
= (char*)p->m_irgendwas < (char*)(p + 1) garantiert ist. (Ich
bin aber nicht sicher darüber.)

Im ersten Teil stimme ich mit Dir überein. Was den Zeigervergleich
angeht bin ich allgemein auch ziemlich unsicher (ich kann den
Paragraphen mit den Garantien für Speicheraddressen im Moment überhaupt
nicht finden).

Ich auch nicht:-). Ich denke aber, dass es der Absicht
entspricht.

Wobei es geht nur um Adressen, die du als Programmierer erhalten
kannst. Mann kann z.B. die vtable als Bestandteil des Objektes
betrachten; immerhin wird sie sicher nicht zwischen den Anfangs-
und Endeadressen liegen. (Siehe aber unten.)

Quote:
Der Rest des Satzes ist wohl wortauslegungssache Wink,
wenn Du mit Grösse den Wert des sizeof() - Operators meinst sage ich
ebenfalls nein - der bezieht sich auf die object-representation des
Objektes (zum Unterschied zur value-representation - und wie die dann
implementiert ist schreibt sowieso niemand vor).

Es ist legal, die klasse foo als Implementation nur mit einem Zeiger auf
z.b. das array auszustatten, dass dann irgendwo liegen kann. Dann wäre
sizeof(foo) == sizeof(internerPointer)

Ich glaube nicht. Gehen wir davon aus, dass ich operator new
ersetzt habe. Damit sind Aufrufe von ihm "sichtbares Verhalten".
Also: wenn man "new foo" schreibt, muss operator new genau
einmal aufgerufen werden, weder mehr noch weniger. Angegeben, er
ermittelt einen Zeiger zurück; nachdem darf keine Ausnahme
auftreten, es sei dann, ich habe es im Constructor explizit
geschrieben. Woher dann soll anderer Speicher kommen?

Das ist das Problem des Compilers Wink
Nein, im Ernst, praktisch gesehen ist das selbstverständlich ein sehr
sehr guter Grund (nebst anderen) dass die value-representation immer ein
Teil der object representation ist. Nur glaube ich nicht dass es
verpflichtet ist - auch nicht implizit über Umwege.

In der Tat ist das Problem des Compilers. Dazu hat der Compiler
immer eine Ausrede: obwohl ich es nicht in der C++-Norm finde,
in C ist es undefiniertes Verhalten, wenn man die
Ressource-Limiten des Systems überschritt. (Nötige Beschränkung,
eigenlich, weil die abstrakte Maschine unendlich ist.) Also,
z.B. will der Compiler Bounds-Checking implementieren. Er kann
dann sagen, dass es eine höchste Anzahl von Zeigern, une einen
Feld mit Descriptoren von Zeigern mit dieser Grösse statisch
anlegen. Dann erfolgt es tatsächlich, dass ein Teil der
Darstellung eines Zeigers anderswo liegt. Nur denke ich, dass es
auch dem Programm transparent sein muss, solange das Programm
nichts unerlaubt (undefiniertes Verhalten) macht, und innerhalb
den Grenzen deiser Ressource-Limite bleibt.

--
James Kanze (GABI Software) email:james.kanze (AT) gmail (DOT) com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Back to top
Thomas Mang
Guest





PostPosted: Fri Apr 13, 2007 10:29 pm    Post subject: Re: Heap-Verständnisfrage Reply with quote

James Kanze wrote:
Quote:
On Apr 12, 1:48 am, Thomas Mang <noth...@provided.com> wrote:
James Kanze wrote:
On Apr 10, 10:01 am, Thomas Mang <noth...@provided.com> wrote:
Thomas Maeder wrote:

Jein. Es kann in Prinzip vorkommen, dass es löcher drin gibt,
aber... sizeof(foo) muss eine Konstante sein, und es muss bei
new foo genau einen Aufruf operator new geben, mit als Parameter
sizeof(foo). Damit sind die Möglichkeiten etwas begrenzt.
Zeigerarithmetik muss auch funktionnieren, wenn man einen Feld
von foo hat; ich glaube sogar, dass angegeben foo* p, (char*)p
= (char*)p->m_irgendwas < (char*)(p + 1) garantiert ist. (Ich
bin aber nicht sicher darüber.)

Im ersten Teil stimme ich mit Dir überein. Was den Zeigervergleich
angeht bin ich allgemein auch ziemlich unsicher (ich kann den
Paragraphen mit den Garantien für Speicheraddressen im Moment überhaupt
nicht finden).

Ich auch nicht:-). Ich denke aber, dass es der Absicht
entspricht.

Ich glaube eher nicht, dass es Absicht war.
In 5.9/2 steht einiges über Garantien für Vergleich von Zeigern auf
Datenmembern. Ich weiß aber nicht inwiefern das dort alles im
Zusammenhang mit der char* - Konvertierung in Deinem Beispiel zu lesen
ist - gelten die konvertierten char* Zeiger noch als zeiger auf
Datenmember (die Datenmember sind ja nicht char)?

Ausserdem, nehmen wir abgeleitete Klassen hinzu. Das object-layout
zwischen Basisklasse und abgeleiteter Klasse ist explizit unspezifiziert
(10.1/3). Dazu kommt noch, dass object-layouts nicht einmal stets ident
sein müssen (10.1/5 - wahrscheinlich primär wegen empty base classes).

Ich glaube es ist klar dass bei:

struct base
{
base() {}
};
struct derived : base
{};

es keine Garantie gibt dass der Teil der abgeleiteten Klasse "hinter"
(also höhere Adresse) der Basisklasse kommt. Hat man ein Objekt D vom
Typ derived, so ist folgendes keinesfalls garantiert:
&static_cast<base>(D) < &D

Wenn wir jetzt einen 'normalen' Compiler nehmen der value-bits stets als
Teil der object-bits implementiert, dann gibt es bei abgeleiteten
Klassen logischerweise keine Garantie dass Daten-member (aus einer
Basisklasse) eine höhere Adresse haben als der this-pointer.

Die einzige echte Garantie die ich kenne ist 9.2/12. Und wie Du treffend
erwähnt hast, Adressen im Zeigersinn müssen ja nicht notwendigerweise
den tatsächlichen Adressen im Speichersystem entsprechen - weder vom
absoluten Wert her, noch bei Vergleichsoperationen mit Zeigern, also was
5.9 / 5.10 garantieren.


Ich kann mir sogar Fälle vorstellen wo ein Compiler mit bestem Gewissen
und mit positivem Resultat Datenmember aus der Objektrepräsentation
auslagert:
Nimm eine Klasse, die relativ groß ist (im Sinne von bytes für die
value-representation), wovon auf die kleinen Datenmember ständig
zugegriffen wird, auf ein paar große (wieder im Sinne von value-bits)
jedoch nur selten (z.b. indem ständig über ein Feld iteriert wird). je
nach Systemarchitektur, cache-Größen und Speicherzugriffskosten kann es
dann sehr wohl Sinn ergeben die Objekte schlank zu machen und nur die
'wichtigsten, kleinen' Datenmember in der Objektrepräsentation zu
speichern, während die 'selten genutzten, grossen' woanders liegen und
im Objekt nur einen Zeiger dorthin gespeichert ist.

Quote:

Das ist das Problem des Compilers Wink
Nein, im Ernst, praktisch gesehen ist das selbstverständlich ein sehr
sehr guter Grund (nebst anderen) dass die value-representation immer ein
Teil der object representation ist. Nur glaube ich nicht dass es
verpflichtet ist - auch nicht implizit über Umwege.

In der Tat ist das Problem des Compilers. Dazu hat der Compiler
immer eine Ausrede: obwohl ich es nicht in der C++-Norm finde,
in C ist es undefiniertes Verhalten, wenn man die
Ressource-Limiten des Systems überschritt. (Nötige Beschränkung,
eigenlich, weil die abstrakte Maschine unendlich ist.)

So weit ich weiß ist das vom C-Standard übernommen worden und noch um
Annex B erweitert worden - wobei der 1) sowieso non-normative ist, und
2) selbst das was da drinnen steht lediglich guidelines sind.

Thomas
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.