Dude: Stack und Heap

Hallo zusammen,

ich habe mal eine ganz grundlegende Frage. Wenn ich mit Qt und C++ programmiere, muss ich das ja notgedrungen objektorientiert machen. Wenn ich also eine Klasse ChatDialog in chatdialog.h anlege und darin ein paar Variablen deklariere, kann ich das ja statisch machen (bspw. QLabel label;) oder dynamisch (Qlabel *label). Beim ersten Fall landet die Variable auf dem Stack im zweiten auf dem Heap. Soweit hab ich das verstanden. Aber worin liegt jetzt der praktische Unterschied für mich als Programmierer außer:

Da der Stack nach der Ausführung der Funktion/Methode wieder automatisch bereinigt wird, werden statische Objekte also automatisch zerstört, wenn die Funktion bzw. Methode beendet ist.

Das hab ich von OOP mit c++

Was bedeutet das denn. Heißt das, dass ich ein statisch deklariertes Label, dass ich dann im Konstruktor implementiere, nach der Ausführung des Konstruktors gelöscht wird?

Wäre für Hilfe sehr dankbar

MfG Dude

  1. Hi,

    Wenn ich mit Qt und C++ programmiere, muss ich das ja notgedrungen objektorientiert machen. Wenn ich also eine Klasse ChatDialog in chatdialog.h anlege und darin ein paar Variablen deklariere, kann ich das ja statisch machen (bspw. QLabel label;) oder dynamisch (Qlabel *label).

    Was bitte soll der Unterschied, ob es sich um eine Eigenschaft vom Typ QLabel, oder um einen Pointer auf QLabel handelt, denn bitte mit statisch oder nicht statisch zu tun haben?

    Meinst du überhaupt statisch im OO-Sinne, also static?

    Da der Stack nach der Ausführung der Funktion/Methode wieder automatisch bereinigt wird, werden statische Objekte also automatisch zerstört, wenn die Funktion bzw. Methode beendet ist.

    Ja.

    Was bedeutet das denn.

    Was verstehst du denn daran nicht?

    Heißt das, dass ich ein statisch deklariertes Label, dass ich dann im Konstruktor implementiere, nach der Ausführung des Konstruktors gelöscht wird?

    Statisch, „Label“ ... ich glaube, du solltest erst mal die Begrifflichkeiten lernen, die in diesem Umfeld üblich sind - sonst können wir uns hier kaum vernünftig darüber unterhalten.

    Wenn du lediglich einen Pointer auf ein Datenobjekt in deiner Klasse ablegst - dann stirbt nur der Pointer, wenn deine Klassen-Instanz weggeräumt wird.
    Der Speicherplatz, der reserviert wurde, als du das Objekt angelegt hast, auf das dieser Pointer verweist, wird dadurch aber nicht freigegeben - dafür hast du selber zu sorgen.
    Dafür gibt es in C++ den delete-Operator.

    MfG ChrisB

    --
    “Whoever best describes the problem is the person most likely to solve the problem.” [Dan Roam]
    1. Was bitte soll der Unterschied, ob es sich um eine Eigenschaft vom Typ QLabel, oder um einen Pointer auf QLabel handelt, denn bitte mit statisch oder nicht statisch zu tun haben?

      An dieser Stelle kann ich nur auf OOP mit C++ verweisen. Punkt 2.3.2

      Wenn du lediglich einen Pointer auf ein Datenobjekt in deiner Klasse ablegst - dann stirbt nur der Pointer, wenn deine Klassen-Instanz weggeräumt wird.

      achso also beim löschen der Instanz! Danke

      Der Speicherplatz, der reserviert wurde, als du das Objekt angelegt hast, auf das dieser Pointer verweist, wird dadurch aber nicht freigegeben - dafür hast du selber zu sorgen.
      Dafür gibt es in C++ den delete-Operator.

      Aha soweit verstanden

    2. Meinst du überhaupt statisch im OO-Sinne, also static?

      Sicher nicht. Die Aussage in seinem Artikel "Statisch erzeugen Sie ein Objekt, indem Sie eine Objektvariable wie eine einfache Variable deklarieren" würde ich als falsch bezeichnen.
      Lokale Variablen in C/C++ sind gebunden an ihren Scope. Wird der Scope betreten, wird diese Variable auf dem Stack angelegt (Prolog). Wird der Scope verlassen, wird sie wieder entfernt(Epilog).
      Wenn ich das nicht möchte, muss man die Variable auf einem der Heaps anlegen(Speicher reservieren). Das macht man z.B. mit malloc/new oder der gleichen. Dort reservierter Speicher bleibt erhalten bis die Variable durch free/delete wieder zerstört wird.
      Statisch Variablen werden mit dem Schlüsselwort static definiert. Lokale statische Variablen werden beim 1. Aufruf angelegt und bleiben bis zum Programmende erhalten. Globale statische Variablen werden bei Programmstart angelegt.

      Da der Stack nach der Ausführung der Funktion/Methode wieder automatisch bereinigt wird, werden statische Objekte also automatisch zerstört, wenn die Funktion bzw. Methode beendet ist.

      Ja.

      Nicht die Objekte, welche ich als statisch bezeichnen würde.

  2. Das hab ich von OOP mit c++

    Der gute Mann schreibt da IMHO einigen Unsinn.

    „Kreis k; // statische Erzeugung
    Statisch bedeutet hier, dass C++ das Objekt auf dem Stack speichert.“

    Die Verwendung von "statisch" ist reichlich unklug, denn unter diesem Attribut versteht man bei OOP etwas gänzlich anderes als das eine Variable (und auch ein Objekt ist eine Variable) einfach auf dem Stack abgelegt wäre. Nichtsdestotrotz könnte man damit noch leben. Aber was dann folgt:

    „Diese statische Erzeugung ist übrigens eine Spezialität von C++. Andere Sprachen, wie Pascal/Delphi, C#, Visual Basic(.NET) und Java kennen keine statisch erzeugten Objekte. In diesen Sprachen werden Objekte immer dynamisch erzeugt.“

    Das ist in dieser Form schlicht und ergreifend – falsch. Das ist sowas von falsch, man sollte dem Mann das Schreiben von Lehrtexten zur Programmierung verbieten. Entweder schreibt man von Objekten, dann hat die Sprache Pascal (und Visual Basic?) da aber nichts zu suchen, denn die kennt keine Objekte, oder man bezieht sich auf Variablen allgemein, dann stimmt die Behauptung, der Stack wäre eine Spezialität von C++ aber nicht.

    Jede deiner Variablen braucht logischerweise Platz im Speicher. Es gibt im Wesentlichen zwei Möglichkeiten, diesen Platz zu bekommen:

    1. Der Stack, zu Deutsch Stapelspeicher. Der Stack ist ein zusammenhängender Speicherblock, den jedes Programm beim Start zugewiesen bekommt. Rufst du eine Funktion A auf, in der du beispielsweise ein int i deklariert hast, benutzt die Funktion A vier Bytes des Stapelspeichers. Ruft diese Funktion A eine weitere Funktion B auf, stapelt die zweite ihre Variablen auf die bereits vorhandenen Variablen von A. Und so geht das immer weiter, mit jedem Aufruf kommen weitere Variablen auf den Stapel, mit jedem Verlassen einer Funktion schrumpft der Stapel wieder.
    Diese Variablen leben und sterben also mit dem Funktionsaufruf. Wohlgemerkt: Aufruf. Ruft A sich selbst auf, stapelt der zweite Aufruf von A seine Variablen auf jenen des ersten Aufrufs von A.

    2. Der Hauptspeicher (der Autor nennt ihn Heap). Du kannst explizit Hauptspeicher vom Betriebssystem anfordern, meinetwegen wieder vier Bytes für dein int. Du bekommst dann vom System die Adresse des Speicherbereichs, kannst über diese Adresse auf die Bytes zugreifen und musst den Speicher wieder freigeben, sobald du ihn nicht mehr brauchst.
    So eine Variable wäre von einem Funktionsaufruf unabhängig, du musst dich aber auch selbst darum kümmern, dass der nötige Speicher vor Variablennutzung reserviert und abschließend freigegeben wird.

    Deine Objekte sind nichts weiter als Variablen mit ein wenig Zusatzfunktionalität. Der Speicher für ein Objekt kann bequem vom Stack genommen (QLabel label) oder aber vom Betriebssystem explizit reserviert werden (label = new QLabel).
    In letzterem Fall beachte, dass du trotzdem noch die Variable label auf dem Stack hast: In ihr ist die Adresse des Objekts gespeichert.

    Diese ganze Vorgehensweise ist _keine_ Spezialität von C++, eigentlich ist das nicht einmal eine Programmiersprachenangelegenheit, sondern obligt vielmehr dem Compiler oder Interpreter und fällt schon halb in den Bereich des Betriebssystems. Selbst bei einer prozessornahen Sprache wie Assembler, wo es keine Variablen im üblichen Sinne gibt, wird der Stack benutzt, und es gibt Konventionen der Prozessorhersteller, welches Prozessorregister die Adresse des Stacks enthalten soll.

    Der Unterschied zwischen Stack und Hauptspeicher (Heap) liegt für dich als Programmierer einfach in deinem Bedarf. Der Stack enthält mehr oder weniger alle lokalen Variablen einer Funktion. Die explizite Reservierung von Speicher wird benutzt, wenn nicht bekannt ist, ob überhaupt, und wenn ja, wie viele Variablen (Daten) anfallen. Bei einem Texteditor kannst du beispielsweise nicht schon bei der Programmierung 100 Zeilen-Objekte vorab fest à la Zeile z[100] auf dem Stack anlegen; sinnvoll ist nur, diese Zeile für Zeile mit new Zeile() zu erzeugen, je nach Bedarf.

    1. Hi,

      „Kreis k; // statische Erzeugung
      Statisch bedeutet hier, dass C++ das Objekt auf dem Stack speichert.“
      Die Verwendung von "statisch" ist reichlich unklug, denn unter diesem Attribut versteht man bei OOP etwas gänzlich anderes als das eine Variable (und auch ein Objekt ist eine Variable) einfach auf dem Stack abgelegt wäre.

      und noch allgemeiner (etwa in C oder Assembler) versteht man unter "statisch" wieder etwas anderes - nämlich Variablen, deren Speicheradresse und Speicherbedarf bereits beim Compilieren festgelegt wird.

      „Diese statische Erzeugung ist übrigens eine Spezialität von C++. Andere Sprachen, wie Pascal/Delphi, C#, Visual Basic(.NET) und Java kennen keine statisch erzeugten Objekte. In diesen Sprachen werden Objekte immer dynamisch erzeugt.“
      Das ist in dieser Form schlicht und ergreifend – falsch. Das ist sowas von falsch, man sollte dem Mann das Schreiben von Lehrtexten zur Programmierung verbieten. Entweder schreibt man von Objekten, dann hat die Sprache Pascal (und Visual Basic?) da aber nichts zu suchen, denn die kennt keine Objekte

      Aber hallo! Moderne Pascal-Varianten kennen sehr wohl Objekte und Klassen. Schon Borland Pascal 7 aus dem Jahr 1990 (so ungefähr jedenfalls) kannte das Konzept von Klassen und OOP, und Delphi, das davon abstammt, erst recht. Für Wuschelbasic will ich mich da nicht aus dem Fenster lehnen, das kenne ich nur vom Hörensagen.

      oder man bezieht sich auf Variablen allgemein, dann stimmt die Behauptung, der Stack wäre eine Spezialität von C++ aber nicht.

      Die stimmt sowieso nicht. Der Stack ist ein Grundkonzept fast aller CPUs, das von vielen Programmiersprachen übernommen und mitgenutzt wird.

      1. Der Stack, zu Deutsch Stapelspeicher.

      Danke, dass du nicht Kellerspeicher sagst. Der Begriff kursierte Anfang der 90er Jahre, als man plötzlich sämtliche EDV-Fachtermini mit Gewalt eindeutschen wollte, mal in diversen Fachbüchern, und Scharen von Programmierern haben sich gefragt, was das wohl sein mag.

      Rufst du eine Funktion A auf, in der du beispielsweise ein int i deklariert hast, benutzt die Funktion A vier Bytes des Stapelspeichers. Ruft diese Funktion A eine weitere Funktion B auf, stapelt die zweite ihre Variablen auf die bereits vorhandenen Variablen von A. Und so geht das immer weiter, mit jedem Aufruf kommen weitere Variablen auf den Stapel, mit jedem Verlassen einer Funktion schrumpft der Stapel wieder.
      Diese Variablen leben und sterben also mit dem Funktionsaufruf. Wohlgemerkt: Aufruf. Ruft A sich selbst auf, stapelt der zweite Aufruf von A seine Variablen auf jenen des ersten Aufrufs von A.

      Das ist soweit richtig, aber all das ist nur eine Sekundärnutzung des Stacks. Der Hauptzweck ist, Rücksprungadressen beim Aufruf von Unterprogrammen (Funktionen) zu speichern, um die Ausführung des Programms nach dem "return" an der richtigen Stelle fortsetzen zu können.

      1. Der Hauptspeicher (der Autor nennt ihn Heap). Du kannst explizit Hauptspeicher vom Betriebssystem anfordern, meinetwegen wieder vier Bytes für dein int. Du bekommst dann vom System die Adresse des Speicherbereichs, kannst über diese Adresse auf die Bytes zugreifen und musst den Speicher wieder freigeben, sobald du ihn nicht mehr brauchst.

      Und du bekommst meistens mehr Speicher, als du eigentlich anforderst. Windows teilt beispielsweise Speicher nur in Portionen von 4kB zu; wenn die Anwendung also 24 Bytes anfordert, bekommt sie 4kB. Das ist aber systemabhängig.

      Der Unterschied zwischen Stack und Hauptspeicher (Heap) liegt für dich als Programmierer einfach in deinem Bedarf. Der Stack enthält mehr oder weniger alle lokalen Variablen einer Funktion.

      Außerdem ist der Stack bei manchen Rechnerplattformen begrenzt. Auf 16bit-Systemen wie DOS oder Windows 3.x und älter kann der Stack maximal 64kB groß werden, bei 32bit-Systemen kann er theoretisch 4GB umfassen, wenn das OS nicht von sich aus eine Bremse reinhaut.

      So long,
       Martin

      --
      Chef:         Zum vierten Mal in dieser Woche erwische ich Sie nun schon beim Zuspätkommen. Was haben Sie dazu zu sagen?
      Angestellter: Dann muss heute Donnerstag sein.
      Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
      1. Hallo Martin.

        1. Der Stack, zu Deutsch Stapelspeicher.
          Danke, dass du nicht Kellerspeicher sagst. Der Begriff kursierte Anfang der 90er Jahre, als man plötzlich sämtliche EDV-Fachtermini mit Gewalt eindeutschen wollte, mal in diversen Fachbüchern, und Scharen von Programmierern haben sich gefragt, was das wohl sein mag.

        Ich finde eingedeutschte Fachbegriffe auch schrecklich – aber der Keller wurde tatsächlich (u.a.) in Deutschland (an meiner Uni :-)) erfunden, nämlich als das "Kellerprinzip".
        (siehe http://de.wikipedia.org/wiki/Kellerspeicher#Geschichte)

        Servus,
        Flo

      2. Und du bekommst meistens mehr Speicher, als du eigentlich anforderst. Windows teilt beispielsweise Speicher nur in Portionen von 4kB zu; wenn die Anwendung also 24 Bytes anfordert, bekommt sie 4kB. Das ist aber systemabhängig.

        Aber doch nur, wenn eine neue Page angefordert wird. In diese legt der Heapmanager dann solange weitere Variablen rein, bis die Page voll ist.

        Das eigentliche Problem unter Windows ist, dass der Heapmanager diesen Speicher für Blöcke kleiner 512k nicht wieder frei gibt, sonder nur decommittet. Allokiert man seinen gesammten eigenen Addrerssraum (2GB unter 32Bit Windows Systemen) mit kleinen Blöcken, gibt diese dann alle wieder frei und versucht dann einen großen Block zu allokieren, geht das schief (unter WinXP SP2 jedenfalls), weil der Heapmanager für kleine Blöcke eine extra Verwaltung hat um die Fragmentierung zu verbessern. Allerdings gibt diese reservierte Pages nicht wieder ans System zurück.

        Außerdem ist der Stack bei manchen Rechnerplattformen begrenzt. Auf 16bit-Systemen wie DOS oder Windows 3.x und älter kann der Stack maximal 64kB groß werden, bei 32bit-Systemen kann er theoretisch 4GB umfassen, wenn das OS nicht von sich aus eine Bremse reinhaut.

        Der Heap doch auch. Mehr als an Adressraum zur Verfügung steht kann man nicht nutzen.

        1. Moin,

          Und du bekommst meistens mehr Speicher, als du eigentlich anforderst. Windows teilt beispielsweise Speicher nur in Portionen von 4kB zu; wenn die Anwendung also 24 Bytes anfordert, bekommt sie 4kB. Das ist aber systemabhängig.
          Aber doch nur, wenn eine neue Page angefordert wird. In diese legt der Heapmanager dann solange weitere Variablen rein, bis die Page voll ist.

          kann es sein, dass du hier die Speicherverwaltung des OS und die der C-Runtime vermischt hast? AFAIK arbeitet die C/C++-Runtime mit malloc() oder dem new-Operator so, wie du beschrieben hast: Sie fordert einen großen Block Speicher vom OS an, und gibt bei jedem malloc()-Aufruf kleine Häppchen davon an das Programm. Divide et impera. ;-)
          Die Speicherverwaltung des OS selbst (hier als Beispiel Windows) macht sowas nicht. Wenn ich von Windows einen Speicherblock mit GlobalAlloc() anfordere, dann kann die anfordernde Funktion sicher sein, dass sie das zugeteilte Segment exklusiv hat, und nicht mit anderen teilen muss. Außerdem, wie schon gesagt, bekomme ich Speicher von Windows immer nur in Vielfachen von 4kB.

          Das eigentliche Problem unter Windows ist, dass der Heapmanager diesen Speicher für Blöcke kleiner 512k nicht wieder frei gibt, sonder nur decommittet.

          Hö?

          Allokiert man seinen gesammten eigenen Addrerssraum (2GB unter 32Bit Windows Systemen) mit kleinen Blöcken, gibt diese dann alle wieder frei und versucht dann einen großen Block zu allokieren, geht das schief (unter WinXP SP2 jedenfalls), weil der Heapmanager für kleine Blöcke eine extra Verwaltung hat um die Fragmentierung zu verbessern.

          Kann ich nicht mit Sicherheit beurteilen; allerdings erscheint mir das merkwürdig, denn einer der Vorteile der virtuellen Speicherverwaltung (nicht zu verwechseln mit der Swapdatei!) ist doch, dass man über die Descriptortabellen die 4kB-Kacheln mit gleichbleibenden virtuellen Adressen lustig im physikalischen Adressraum hin- und herschieben kann. So kann man Fragmentierung von vornherein vermeiden, bzw. sie ist aus Applikationssicht nicht erkennbar. Sie entsteht erst, wenn man diesem Speichermanager des OS noch eine zweite Schicht der Speicherverwaltung vorschaltet.

          Außerdem ist der Stack bei manchen Rechnerplattformen begrenzt. Auf 16bit-Systemen wie DOS oder Windows 3.x und älter kann der Stack maximal 64kB groß werden, bei 32bit-Systemen kann er theoretisch 4GB umfassen, wenn das OS nicht von sich aus eine Bremse reinhaut.
          Der Heap doch auch. Mehr als an Adressraum zur Verfügung steht kann man nicht nutzen.

          Stimmt. Aber die maximale Größe des Stacks legt der Programmierer vorher fest, und die kann wesentlich kleiner ausfallen, z.B. 1MB. Bei dieser Festlegung muss er natürlich den Bedarf seines Programms ungefähr abschätzen können. So wäre es übertrieben, für ein Programm mit überwiegend linearem Programmablauf und wenig lokalen Daten einen 16MB-Stack zu reservieren; umgekehrt wird man den Stack nicht auf 64kB begrenzen, wenn man ein Programm mit zahlreichen Rekursionen und üppig funktionslokalen Daten hat.

          So long,
           Martin

          --
          Die Zeit, die man zur Fertigstellung eines Projekts wirklich braucht, ist immer mindestens doppelt so lang wie geplant.
          Wurde dieser Umstand bei der Planung bereits berücksichtigt, gilt das Prinzip der Rekursion.
          Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
          1. Hallo,

            Und du bekommst meistens mehr Speicher, als du eigentlich anforderst. Windows teilt beispielsweise Speicher nur in Portionen von 4kB zu; wenn die Anwendung also 24 Bytes anfordert, bekommt sie 4kB. Das ist aber systemabhängig.
            Aber doch nur, wenn eine neue Page angefordert wird. In diese legt der Heapmanager dann solange weitere Variablen rein, bis die Page voll ist.

            kann es sein, dass du hier die Speicherverwaltung des OS und die der C-Runtime vermischt hast?

            Ja, diese sind ja auch vermischt. Bzw. bist eigentlich du über die CRT hinausgegangen und hast die Speicherverwaltung des Systems ins Spiel gebracht.
            Für mich hat sich das angehört(man hätte es so deuten können), als wolltest du sagen, daß unter Windows für jede dynamisch erzeugte Variable immer ein vielfaches der Pagesize an Speicher reserviert wird.
            Das ist aber nicht so.

            AFAIK arbeitet die C/C++-Runtime mit malloc() oder dem new-Operator so, wie du beschrieben hast: Sie fordert einen großen Block Speicher vom OS an, und gibt bei jedem malloc()-Aufruf kleine Häppchen davon an das Programm. Divide et impera. ;-)

            Das kommt auf die CRT und das BS an. Wenn wir über Windows reden, dort existiert ein »» Heapmanagement im Kernel. Inwieweit die CRT diese nutzt oder nicht, ist deren Implementationsdetail.
            Im MS-Compiler wurde bis CRT8.0 für Blöcke bis einschliesslich 480 Byte eine eigene Heapverwaltung in der CRT implementiert und erst für grössere der Windows-Heapmanager verwendet.

            Wenn ich von Windows einen Speicherblock mit GlobalAlloc() anfordere, ...

            GlobalAlloc nutzt auch einen Windows Heap. Nur einen anderen als die CRT. Eine Page reserviert man mit VirtualAlloc, auch der Windows-Heapmanager.

            Das eigentliche Problem unter Windows ist, dass der Heapmanager diesen Speicher für Blöcke kleiner 512k nicht wieder frei gibt, sonder nur decommittet.

            Hö?

            Der Windows-Heapmanager ruft nie VirtualFree mit MEM_RELEASE für diese Bereiche auf (für einen Low Fragmentation Heap).

            einer der Vorteile der virtuellen Speicherverwaltung (nicht zu verwechseln mit der Swapdatei!) ist doch, dass man über die Descriptortabellen die 4kB-Kacheln mit gleichbleibenden virtuellen Adressen lustig im physikalischen Adressraum hin- und herschieben kann. So kann man Fragmentierung von vornherein vermeiden, bzw. sie ist aus Applikationssicht nicht erkennbar.

            Das verstehe ich nicht ganz, ich rede von der Fragmentierung innerhalb der Heaps.
            2K anlegen => 4K anlegen => 2K anlegen => 4K anlegen => 2K löschen => die anderen 2K löschen
            => 4K anlegen

            1. Hi,

              kann es sein, dass du hier die Speicherverwaltung des OS und die der C-Runtime vermischt hast?
              Ja, diese sind ja auch vermischt. Bzw. bist eigentlich du über die CRT hinausgegangen und hast die Speicherverwaltung des Systems ins Spiel gebracht.

              ich hatte bei der Diskussion nie die Speicherverwaltung der C-Runtime im Sinn, sondern ausschließlich die des OS.

              Wenn ich von Windows einen Speicherblock mit GlobalAlloc() anfordere, ...
              GlobalAlloc nutzt auch einen Windows Heap. Nur einen anderen als die CRT. Eine Page reserviert man mit VirtualAlloc, auch der Windows-Heapmanager.

              Dann reden wir tatsächlich von unterschiedlichen Dingen, und sollten erstmal klären, was wir unter "Heap" verstehen. Ich verstehe darunter jedenfalls die Gesamtheit des Arbeitsspeichers, den eine Applikation vom Betriebssystem "anfordern" und nutzen kann. Du scheinst unter "Heap" jedoch ein internes Management in der Applikation (bzw. deren Runtime-Umgebung) zu verstehen.

              Um ehrlich zu sein: Mir war VirtualAlloc() bisher völlig unbekannt, ich habe den Speicherbedarf meiner Anwendungen immer mit GlobalAlloc() und GlobalFree() organisiert. Und auch nach dem Lesen der Beschreibung in der Win32-Referenz wird mir nicht ganz klar, was die Funktion VirtualAlloc() wirklich tut bzw. worin ihr Daseinszweck besteht.

              einer der Vorteile der virtuellen Speicherverwaltung (nicht zu verwechseln mit der Swapdatei!) ist doch, dass man über die Descriptortabellen die 4kB-Kacheln mit gleichbleibenden virtuellen Adressen lustig im physikalischen Adressraum hin- und herschieben kann. So kann man Fragmentierung von vornherein vermeiden, bzw. sie ist aus Applikationssicht nicht erkennbar.
              Das verstehe ich nicht ganz, ich rede von der Fragmentierung innerhalb der Heaps.

              Also innerhalb von Speicherbereichen, die von der Applikation selbst verwaltet werden? Dann bin ich raus aus der Nummer, das hatte ich nie gemeint. Ich sprach ausschließlich von der Speicherverwaltung durch das OS; das Speichermanagement der Applikation ist ja quasi nur Untermieter davon.

              Ciao,
               Martin

              --
              "Hier steht, deutsche Wissenschaftler hätten es im Experiment geschafft, die Lichtgeschwindigkeit auf wenige Zentimeter pro Sekunde zu verringern." - "Toll. Steht da auch, wie sie es gemacht haben?" - "Sie haben den Lichtstrahl durch eine Behörde geleitet."
              Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
              1. Dann reden wir tatsächlich von unterschiedlichen Dingen, und sollten erstmal klären, was wir unter "Heap" verstehen.

                Die von new/delete verwendete Speicherverwaltung.

                Und auch nach dem Lesen der Beschreibung in der Win32-Referenz wird mir nicht ganz klar, was die Funktion VirtualAlloc() wirklich tut bzw. worin ihr Daseinszweck besteht.

                Eine/mehrere Pages aus dem Adressraum des Prozesses vom System zu holen. In diese Pages kann man dann Code oder Daten legen.
                GlobalAlloc() nutzt HeapAlloc() und HeapAlloc() nutzt VirtualAlloc().

      3. Hallo,

        Die Verwendung von "statisch" ist reichlich unklug, denn unter diesem Attribut versteht man bei OOP etwas gänzlich anderes als das eine Variable (und auch ein Objekt ist eine Variable) einfach auf dem Stack abgelegt wäre.

        Diese Bezeichnung ist in diesem Kontext korrekt. In der Tat ist es aber wichtig genau zwischen statischer Speicherbelegung und 'static' Schlüsselwort zu unterscheiden.

        und noch allgemeiner (etwa in C oder Assembler) versteht man unter "statisch" wieder etwas anderes - nämlich Variablen, deren Speicheradresse und Speicherbedarf bereits beim Compilieren festgelegt wird.

        Ich würde das nicht als 'noch allgemeiner' sondern als die eigentliche Bedeutung sehen.

        Statische Objekterzeugung heißt, dass der Speicher des angegebenen Objekttyps eingebettet wird. Das heißt, es wird die für das Objekt benötigte Speichergröße reserviert und direkt eingebettet, entweder auf dem Stack während der Ausführung einer Methode oder aber als eingebettete Instanz in einem anderen Objekt.
        (z.B. QLabel label;)

        Dynamische Objekterzeugung heißt, dass die benötigte Speichergröße auf dem Heap (dynamisch zugeteilter Speicher) belegt wird. Am Ende dieser Speicherbelegung erhält der Programmierer einen Zeiger (Speicheradresse) auf den belegten Speicher. Diesen Zeiger kann er wiederum in einer statisch oder dynamisch erzeugten Zeigervariablen speichern, um mit dem Objekt arbeiten und es später freigeben zu können.
        (z.B. QLabel *label;)

        Was die Verwendung angeht, sollte man Wissen, dass der Zugriff auf statisch erzeugte Objekte bedeutend schneller ist, da in diesem Fall kein Zeiger dereferenziert werden muss und keine Seitenfehler auftreten.

        „Diese statische Erzeugung ist übrigens eine Spezialität von C++. Andere Sprachen, wie Pascal/Delphi, C#, Visual Basic(.NET) und Java kennen keine statisch erzeugten Objekte. In diesen Sprachen werden Objekte immer dynamisch erzeugt.“

        Das ist in dieser Form schlicht und ergreifend – falsch. Das ist sowas von falsch, man sollte dem Mann das Schreiben von Lehrtexten zur Programmierung verbieten.

        Dem kann ich mich nur anschliessen.

        1. Was die Verwendung angeht, sollte man Wissen, dass der Zugriff auf statisch erzeugte Objekte bedeutend schneller ist, da in diesem Fall kein Zeiger dereferenziert werden muss und keine Seitenfehler auftreten.

          Die Zeigerei sollte nicht überbewertet werden. Auch statische Objekte werden intern über Zeiger, also Adressen angesprochen, es sei denn, der Compiler ist so schlau (und vor allem das Objekt bzw. die Variable so klein), dass er ein Objekt direkt in einem Prozessorregister halten kann. Dass bei dynamischen Objekten zwei Speicherzugriffe notwendig sind, erst zum Holen der Adresse aus der Zeigervariablen, dann zum Holen der Daten mittels dieser Adresse, halte ich für vernachlässigbar.

          Seitenfehler sind beim Stapelspeicher allerdings vergleichsweise unwahrscheinlich, das ist richtig.

          1. Hallo,

            Die Zeigerei sollte nicht überbewertet werden.
            Dass bei dynamischen Objekten zwei Speicherzugriffe notwendig sind, erst zum Holen der Adresse aus der Zeigervariablen, dann zum Holen der Daten mittels dieser Adresse, halte ich für vernachlässigbar.

            Das ist Ansichtsache und findet heutzutage tatsächlich weniger Beachtung.

            Auch statische Objekte werden intern über Zeiger, also Adressen angesprochen, es sei denn, der Compiler ist so schlau (und vor allem das Objekt bzw. die Variable so klein), dass er ein Objekt direkt in einem Prozessorregister halten kann.

            Hallo?
            Es werden immer nur
            1. Variablenwerte bis zu einer maximalen Größe der Prozessorarchitektur (z.B. 64 Bit) wie zum Beispiel die Basistypen Integer, Byte usw.
            2. Speicheradressen (Größe der Prozessurarchitektur z.B. 64 Bit) in die Prozessorregister geladen.
            Objekte haben in dieser Abstraktionsebene nichts zu suchen.

            MfG

        1. Der Stack, zu Deutsch Stapelspeicher.

        Danke, dass du nicht Kellerspeicher sagst. Der Begriff kursierte Anfang der 90er Jahre, als man plötzlich sämtliche EDV-Fachtermini mit Gewalt eindeutschen wollte, mal in diversen Fachbüchern, und Scharen von Programmierern haben sich gefragt, was das wohl sein mag.

        Der Begriff Kellerspeicher taucht im deutschen Patent 1094019 auf, welches von den deutschen Erfindern des Prinzips 1957 beantragt wurde – soviel zu gewaltsamer Eindeutschung und den 90ern. Und Programmierern, die glauben, alle Ideen müssten aus dem englischen Sprachraum stammen oder zumindest englische Bezeichnungen haben, um so richtig richtig zu sein. (Dieser Schwachsinn wird an immer mehr deutschen Schulen weitergeführt: Biologie, Erdkunde, Sport wird seit einigen Jahren auf Englisch unterrichtet. Die Alpen heißen bei meiner Nichte "alps" und die Nachbarskinder rufen beim Spielen "Ready, set, go!". Erbärmlich. Traurig.)

        Ich für meinen Teil bleibe beim Stapelspeicher, das ist eine sehr schöne Beschreibung des Funktionsprinzips, die auch Unbedarfte verstehen.

        Das ist soweit richtig, aber all das ist nur eine Sekundärnutzung des Stacks. Der Hauptzweck ist, Rücksprungadressen beim Aufruf von Unterprogrammen (Funktionen) zu speichern, um die Ausführung des Programms nach dem "return" an der richtigen Stelle fortsetzen zu können.

        Das ist _auch_ ein Zweck. Darum geht's hier aber nicht, die Frage drehte sich um "Stack"- und "Heap"-Variablen.

        Außerdem ist der Stack bei manchen Rechnerplattformen begrenzt. Auf 16bit-Systemen wie DOS oder Windows 3.x und älter kann der Stack maximal 64kB groß werden, bei 32bit-Systemen kann er theoretisch 4GB umfassen

        Die Adressbreite des Systems begrenzt immer jeden Speicher, nicht nur manchmal und nicht nur den Stapelspeicher. Der Stapelspeicher im Speziellen ist begrenzt, weil er üblicherweise beim Programmstart am Stück reserviert wird und dann ohne unverhältnismäßigen Aufwand nicht mehr vergrößert werden kann. Er muss also von Anfang an groß genug sein, darf aber anderen im System auch nicht den Platz wegnehmen.

        1. Hallo,

          1. Der Stack, zu Deutsch Stapelspeicher.
            Danke, dass du nicht Kellerspeicher sagst. Der Begriff kursierte Anfang der 90er Jahre, als man plötzlich sämtliche EDV-Fachtermini mit Gewalt eindeutschen wollte, mal in diversen Fachbüchern, und Scharen von Programmierern haben sich gefragt, was das wohl sein mag.
            Der Begriff Kellerspeicher taucht im deutschen Patent 1094019 auf, welches von den deutschen Erfindern des Prinzips 1957 beantragt wurde – soviel zu gewaltsamer Eindeutschung und den 90ern.

          der Begriff an sich ist natürlich älter, keine Frage. Aber es gab in den frühen 90er Jahren, als Computer so allmählich ein Thema für die breite Öffentlichkeit wurden, das Bestreben, die bis dato vorherrschende englische Sprache zugunsten der eigenen Landessprache zurückzudrängen. Dass man in diesem Zug anfing, die Benutzerschnittstelle von Programmen ins Deutsche zu übersetzen, ist völlig okay und angebracht. Dass man aber auch anfing, englische Fachbegriffe einzudeutschen, die sich in der Branche schon lange etabliert hatten, ging wohl ein wenig übers Ziel hinaus.
          Und in der Phase haben eben auch manche Hochschulen und Fachverlage versucht, den Ausdruck "Kellerspeicher" zu vermitteln.

          Und Programmierern, die glauben, alle Ideen müssten aus dem englischen Sprachraum stammen oder zumindest englische Bezeichnungen haben, um so richtig richtig zu sein.

          Ach je, nein! Schließlich kamen auch einige Pioniere der Elektronik, Nachrichtentechnik und EDV aus dem deutschen Sprachraum. Aber dennoch ist Englisch die branchenübliche Sprache. Ich kritisiere nicht, deutsche Begriffe zu verwenden! Ich kritisiere nur, sie einführen zu wollen, wenn ein großer Teil der Betroffenen sich bereits an einen englischen Begriff gewöhnt hat.

          (Dieser Schwachsinn wird an immer mehr deutschen Schulen weitergeführt: Biologie, Erdkunde, Sport wird seit einigen Jahren auf Englisch unterrichtet. Die Alpen heißen bei meiner Nichte "alps" und die Nachbarskinder rufen beim Spielen "Ready, set, go!". Erbärmlich. Traurig.)

          Das ist echt Schwachsinn.

          Ich für meinen Teil bleibe beim Stapelspeicher, das ist eine sehr schöne Beschreibung des Funktionsprinzips, die auch Unbedarfte verstehen.

          Ja, das finde ich auch gut - zumal Stapelspeicher und Stack als Entsprechung auch leicht zu merken ist und beide Begriffe sehr anschaulich sind. Dass der Stack bei den meisten Prozessoren "von oben nach unten" wächst, also in Richtung kleinerer Speicheradressen (daher kam ja der Ausdruck "Kellerspeicher"), ist ein Detail, das selbst Programmierer nur im Ausnahmefall interessieren muss. Die Assoziation eines Stapels, auf den man immer neues oben drauflegt und das zuletzt aufgelegte auch zuerst wieder entfernen muss, ist daher völlig angemessen.

          Außerdem ist der Stack bei manchen Rechnerplattformen begrenzt. Auf 16bit-Systemen wie DOS oder Windows 3.x und älter kann der Stack maximal 64kB groß werden, bei 32bit-Systemen kann er theoretisch 4GB umfassen
          Die Adressbreite des Systems begrenzt immer jeden Speicher, nicht nur manchmal und nicht nur den Stapelspeicher. Der Stapelspeicher im Speziellen ist begrenzt, weil er üblicherweise beim Programmstart am Stück reserviert wird und dann ohne unverhältnismäßigen Aufwand nicht mehr vergrößert werden kann. Er muss also von Anfang an groß genug sein, darf aber anderen im System auch nicht den Platz wegnehmen.

          Das einerseits; ich meinte aber auch, dass er durch die Prozessorarchitektur bedingt häufig nicht den gesamten Adressraum nutzen kann. Das Beispiel der 16bit-x86-Architektur habe ich bereits erwähnt (1MB Adressraum, 64kB Stack), ein anderes, eher historisches ist die 8bit-CPU 6502 (die mit leichten Variationen als 6510 vor allem durch die Verwendung im C64 berühmt wurde), die einen Adressraum von 64kB hat, aber nur 256 Bytes davon als Stack nutzen kann.

          So long,
           Martin

          --
          Most experts agree: Any feature of a program that you can't turn off if you want to, is a bug.
          Except with Microsoft, where it is just the other way round.
          Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
      4. Hello,

        Aber hallo! Moderne Pascal-Varianten kennen sehr wohl Objekte und Klassen. Schon Borland Pascal 7 aus dem Jahr 1990 (so ungefähr jedenfalls) kannte das Konzept von Klassen und OOP, und Delphi, das davon abstammt, erst recht. Für Wuschelbasic will ich mich da nicht aus dem Fenster lehnen, das kenne ich nur vom Hörensagen.

        Und nicht vergessen sollt man, dass der Heap (verbleibender Hauptspeicher) in diesen Sprachen auf zwei Weisen zugeteilt wird:

        Bereits bei Programmstart für alle bis zu diesem Zeitpunkt bereits bekannten Variablen, also die statisch bestimmten Variablen. Erreichbar sind diese denn über eine Adresse eines/des Datensegmentes und ändern ihre Adressen auch nicht während des Betriebes.

        Während des Programmlaufes durch allokieren von Speicher aus dem restlichen verfügbaren Bereich. Dieser wird dann über einen Deskriptor des Programm-Rahmes oder des OS beschrieben. Festgelegt werden dabei meistens nur Lage und Größe, bei streng typisierenden Sprachen ggf. noch der Typ. Bei Typisierten Speicherblöcken muss dies die Sprache selber besorgen.

        Danke, dass du nicht Kellerspeicher sagst.

        Dann solltest Du auch noch erzählen, warum die damaligen Deutschler auf diesen Begriff kamen. Der Stack muss(te) bei Programmstart in einer gewünschtren Größe reserviert werden. Gezählt wurd dann abwärts bis zum Erreichen von 0. Das war dann "Stack-Overflow". Kennt man vom guten alten DOS ja noch zur Genüge. Das hatte intern mehrere Stacks für die verschiedenen Aufgaben, was aber meistens trotzdem nocb nicht gereicht hat, um Programme stabil zu bekommen. Wenn mehr oder größere vereinbart hat, war meistens nicht mehr genugt Speicher fürs eigentliche Programm da :-(

        Liebe Grüße aus dem schönen Oberharz

        Tom vom Berg

        --
         ☻_
        /▌
        / \ Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
  3. ich habe mal eine ganz grundlegende Frage. Wenn ich mit Qt und C++ programmiere, muss ich das ja notgedrungen objektorientiert machen. Wenn ich also eine Klasse ChatDialog in chatdialog.h anlege und darin ein paar Variablen deklariere, kann ich das ja statisch machen (bspw. QLabel label;) oder dynamisch (Qlabel *label). Beim ersten Fall landet die Variable auf dem Stack im zweiten auf dem Heap. Soweit hab ich das verstanden. Aber worin liegt jetzt der praktische Unterschied für mich als Programmierer außer:

    Die Terminologie "statisch" wurde ja schon zu recht hier kritisiert. Als Ergänzung möchte ich anmerken, dass Objekte, die mit

    Qlabel label;

    erzeugt werden, auch als "automatische Variablen" bezeichnet werden. Das ist insofern auch schlüssiger, als dass der Speicherbereich auf dem Stack beim Eintreten in die Funktion automatisch reserviert und beim Verlassen der Funktion automatisch wieder freigegeben wird. "Statische" Variablen in C/C++ sind eher jene mit dem vorangestellten Keyword 'static'.

    Da der Stack nach der Ausführung der Funktion/Methode wieder automatisch bereinigt wird, werden statische Objekte also automatisch zerstört, wenn die Funktion bzw. Methode beendet ist.

    Genau, _automatische_ Objekte werden automatisch zerstört... ;)

    Beim Stack und beim Heap gibt es für den Programmierer ein paar praktische Unterschiede:

    1. Der Stack ist größenbegrenzt, und zwar i.d.R. deutlich kleiner als der zur Verfügung stehende Hauptspeicher. Das heißt, dass Dir eine Funktion wie

    int f(int N) {
      double array[N];
      ...
    }

    um die Ohren fliegt, sobald N einen (i.d.R. nicht allzugroßen) Grenzwert überschreitet. Demgegenüber kannst Du bei Allozierung mit malloc oder new auf dem Heap anhand des Rückgabewerts prüfen, ob die Speicherreservierung erfolgreich war und ggf. den Fehler abfangen.

    1. Der Stack ist 'schneller' als der Heap.
      Der Zugriff auf Stack-Speicher ist meist erheblich schneller als auf Heap-Speicher. Grund: Die Stackbelegung ist meist nicht übermäßig groß, der Stack wird fast ständig benötigt und befindet sich daher mit hoher Sicherheit komplett im Prozessorcache. In der Praxis kann das bei Iterationsschleifen mit zahlreichen Variablen-Zugriffen im Vergleich Stack vs. Heap locker einen Faktor 2-3 oder mehr ausmachen.

    Das ganze hängt natürlich stark davon ab, welche Prozessor- und Speicherhardware verwendet wird. Meine obigen Angaben beziehen sich auf heutige Standard-PCs, auf irgendwelchen exotischen Hardware-Plattformen kann das natürlich ganz anders aussehen.

    Viele Grüße

    Andreas

    1. Hallo,

      Die Terminologie "statisch" wurde ja schon zu recht hier kritisiert. Als Ergänzung möchte ich anmerken, dass Objekte, die mit

      Qlabel label;

      erzeugt werden, auch als "automatische Variablen" bezeichnet werden.

      Wo(/Von wem) werden Objekte als "automatische Variablen" bezeichnet?

      "Statische" Variablen in C/C++ sind eher jene mit dem vorangestellten Keyword 'static'.

      Man sollte zwischen statischer Speicherzuweisung und dem Schlüsselwort 'static' unterscheiden. Beide haben gar nichts miteinander zu tun.

      MfG

      1. erzeugt werden, auch als "automatische Variablen" bezeichnet werden.
        Wo(/Von wem) werden Objekte als "automatische Variablen" bezeichnet?

        http://en.wikipedia.org/wiki/Static_variable

        1. Hallo,

          erzeugt werden, auch als "automatische Variablen" bezeichnet werden.
          Wo(/Von wem) werden Objekte als "automatische Variablen" bezeichnet?
          http://en.wikipedia.org/wiki/Static_variable

          ich kann keinen Satz finden in dem "Objekte" als "Variablen" bezeichnet werden.
          Ich fragte nicht nach einer Definition für "Automatische Variablen" sondern nach einer Aussage die Objekte als Variablen bezeichnet und glaube dass man meine Fragestellung unmissverständlich ist.

          MfG

          1. Hi,

            http://en.wikipedia.org/wiki/Static_variable
            ich kann keinen Satz finden in dem "Objekte" als "Variablen" bezeichnet werden.

            offensichtlich liegt hier ein Missverständnis vor.
            Wir haben hier viele OOP-Nutzer, die "Objekt" sofort mit "Instanz einer Klasse" assoziieren. Dass das Konzept vieler Programmiersprachen den Begriff aber viel allgemeiner fasst, wird übersehen. Für den Programmierer, der etwas in die Speicherorganisation und die Interna von Programmiersprachen eindringt, sind einfache oder strukturierte Variablen, Funktionen, Zeiger, usw. alles Objekte im Sinne von "etwas Sinnvolles, das im Arbeitsspeicher liegt".

            So long,
             Martin

            --
            Realität ist eine Illusion, die durch Unterversorgung des Körpers mit Alkohol entstehen kann.
            Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
            1. Hallo,

              offensichtlich liegt hier ein Missverständnis vor.
              Wir haben hier viele OOP-Nutzer, die "Objekt" sofort mit "Instanz einer Klasse" assoziieren. Dass das Konzept vieler Programmiersprachen den Begriff aber viel allgemeiner fasst, wird übersehen. Für den Programmierer, der etwas in die Speicherorganisation und die Interna von Programmiersprachen eindringt, sind einfache oder strukturierte Variablen, Funktionen, Zeiger, usw. alles Objekte im Sinne von "etwas Sinnvolles, das im Arbeitsspeicher liegt".

              Objekte als "etwas Sinnvolles, das im Arbeitsspeicher liegt", sehe ich genauso.
              Nur ausgerechnet Variablen passen da überhaupt nicht hin.
              Eine Variable ist eine "Hülle" (Container) für einen Wert (Objekt, Zeiger, Funktionszeiger, auch Instanzen von C-Strukturen würde ich als Objekt gelten lassen).
              Eine Variable kann verschiedene Werte annehmen, trotzdem ist sie kein Wert.
              Sie ist ein Platzhalter im Code und kein Wert im Arbeitsspeicher.

              MfG

              1. Hallo Martin,

                offensichtlich liegt hier ein Missverständnis vor.

                ich glaube auch, dass Andreas Pflug durchaus zwischen Objekt und Variable unterscheiden kann.
                Ich fand nur seine Ausdrucksweise sehr missverständlich und verwirrend für einen Programmieranfanger, wie den Fragesteller.

                MfG

              2. Hi,

                Objekte als "etwas Sinnvolles, das im Arbeitsspeicher liegt", sehe ich genauso.
                Nur ausgerechnet Variablen passen da überhaupt nicht hin.

                hmm, ja, doch, gewissermaßen.

                Eine Variable ist eine "Hülle" (Container) für einen Wert (Objekt, Zeiger, Funktionszeiger, auch Instanzen von C-Strukturen würde ich als Objekt gelten lassen).

                Eigentlich ist eine Variable nichts weiter als ein Name für einen Speicherplatz, und somit direkt mit einem Objekt (nach dem eben beschriebenen Verständnis) assoziiert. Daher würde ich auch die vereinfachte Aussage, eine Variable sei ein Objekt, durchaus gelten lassen.
                Eine Variable existiert darüber hinaus nur im Quellcode, und hier ist sie außer mit einer Speicheradresse auch noch mit Metainformationen über ihren Typ, Scope usw. verknüpft; in einem lauffähig übersetzten Programm (z.B. C oder Assembler) gibt es keine Variablen mehr, denn hier sind alle Speicherbezüge aufgelöst.

                Eine Variable kann verschiedene Werte annehmen

                Genauer: Der Speicherplatz, mit dem eine Variable assoziiert ist, kann verschiedene Werte enthalten.

                Sie ist ein Platzhalter im Code und kein Wert im Arbeitsspeicher.

                Ich würde wegen der direkten Beziehung beides durchgehen lassen und daher auch die Aussage "eine Variable ist auch ein Objekt" hinnehmen.

                Ciao,
                 Martin

                --
                Zwei Freundinnen tratschen: "Du, stell dir vor, die Petra kriegt ein Kind!" - "Ich kann mir schon denken, von wem." - "Dann ruf sie mal schnell an, das würde ihr bestimmt weiterhelfen."
                Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                1. Hallo Martin,

                  Ich würde wegen der direkten Beziehung beides durchgehen lassen und daher auch die Aussage "eine Variable ist auch ein Objekt" hinnehmen.

                  wenn Du diesen Gedanken weiterführst kommst Du aber spätestens bei dynamisch erzeugten Objekten in Erklärungsnöte.

                  das in dieser Zeile

                  new QLabel();

                  erzeugte Objekt würdest Du sicher nicht als Variable bezeichnen.

                  QLabel label;
                  und
                  QLabel *label;

                  sind Variablen. Das eine kann eine Objekt-Instanz enthalten und das andere eine Speicheradresse einer Objekt-Instanz. Die enthaltenen Werte können geändert werden.
                  Ändern sich dadurch die Variablen? - Ich glaube, die Antwort darauf trennt uns.
                  Ich würde diese Frage mit NEIN beantworten.

                  Wenn Du mal zur Mathematik schaust ist es doch auch eindeutig festgelegt. Eine Variable ist ein Platzhalter. In der Programmierung wird diesem Platzhalter, wie Du richtig sagtest, zusätzlich ein Typ zugewiesen.

                  Wenn Du das hier betrachtest

                  int x = 5;
                  int y = 5;

                  kämst Du doch sicher nicht auf den Gedanken zu sagen x und y sind die gleichen Variablen.

                  MfG

                  1. das in dieser Zeile

                    new QLabel();

                    erzeugte Objekt würdest Du sicher nicht als Variable bezeichnen.

                    Doch, hier wird eine temp. Variable erzeugt. Diese Variable ist ein Objektpointer vom Typ QLabel*

                    Wenn Du das hier betrachtest

                    int x = 5;
                    int y = 5;

                    kämst Du doch sicher nicht auf den Gedanken zu sagen x und y sind die gleichen Variablen.

                    Nein, sie haben nur den gleichen Wert.

                    Aber worauf willst du eigentlich hinaus?

                    Was an der Aussage

                    Als Ergänzung möchte ich anmerken, dass Objekte, die mit

                    Qlabel label;

                    erzeugt werden, auch als "automatische Variablen" bezeichnet werden.

                    passt dir denn nicht?
                    Hier wird ein Objekt erzeugt, also die Variable label vom Typ Qlabel ist ein Objekt.
                    Da diese auf dem Stack erzeugt wird, wird sie auch als automatische Variable bezeichnet.

                    1. Hallo unknown,

                      das in dieser Zeile

                      new QLabel();

                      erzeugte Objekt würdest Du sicher nicht als Variable bezeichnen.
                      Doch, hier wird eine temp. Variable erzeugt. Diese Variable ist ein Objektpointer vom Typ QLabel*

                      Also setzt Du schon das Speichern eines Rückgabewertes im Prozessorregister mit dem Deklarieren einer Variablen gleich?

                      Wenn Du das hier betrachtest

                      int x = 5;
                      int y = 5;

                      kämst Du doch sicher nicht auf den Gedanken zu sagen x und y sind die gleichen Variablen.
                      Nein, sie haben nur den gleichen Wert.

                      Aber worauf willst du eigentlich hinaus?

                      "Nein, sie haben nur den gleichen Wert." -> darauf will ich hinaus.
                      Wenn ich die Begriffe Objekt und Variable als austauschbar behandle müsste ich sagen können das x und y die gleiche Variable sind.

                      Was an der Aussage

                      Als Ergänzung möchte ich anmerken, dass Objekte, die mit

                      Qlabel label;

                      erzeugt werden, auch als "automatische Variablen" bezeichnet werden.
                      passt dir denn nicht?
                      Hier wird ein Objekt erzeugt, also die Variable label vom Typ Qlabel ist ein Objekt.
                      Da diese auf dem Stack erzeugt wird, wird sie auch als automatische Variable bezeichnet.

                      Für mich passiert bei

                      Qlabel label;

                      das hier:

                      Es wird eine Variable vom Typ QLabel mit Namen label deklariert (Speicherplatz belegt, da automatische Variable).
                      Abhängig von der Programmiersprache wird eine Initialisierung vorgenommen, in OOP Aufruf von Standardkonstruktor.
                      In C-Strukturen passiert gar nichts außer der Speicherbelegung, ebenso bei Integer und so weiter. Meinst Du, dass man bei letzterem von Objekten/Werten sprechen kann?

                      Diese Aussage

                      die Variable label vom Typ Qlabel ist ein Objekt

                      kann ich so nicht nachvollziehen und ich wüßte auch nicht wie ich da eine Brücke bauen kann. Insofern erscheint mir eine weitere Diskussion nicht sinnvoll.

                      MfG

                      1. Hallo karsten76,

                        Also setzt Du schon das Speichern eines Rückgabewertes im Prozessorregister mit dem Deklarieren einer Variablen gleich?

                        Das ist vielleicht etwas übertrieben ausgedrückt und es wird auch keine Variable explizit deklariert, sondern nur temporär erzeugt, aber ja, das mache ich.
                        Und nicht nur ich
                        http://msdn.microsoft.com/en-us/library/bbt3ewya%28VS.80%29.aspx
                        http://www.ibm.com/developerworks/aix/library/au-code_prob.html

                        "Nein, sie haben nur den gleichen Wert." -> darauf will ich hinaus.
                        Wenn ich die Begriffe Objekt und Variable als austauschbar behandle müsste ich sagen können das x und y die gleiche Variable sind.

                        Das verstehe ich nicht. Warum sollen 2 Objekte nicht den gleichen Wert haben dürfen?

                        In C-Strukturen passiert gar nichts außer der Speicherbelegung, ebenso bei Integer und so weiter. Meinst Du, dass man bei letzterem von Objekten/Werten sprechen kann?

                        Ja, von Objekten kann ich sprechen. Diese haben Werte. Setzt du Werte mit Objekten gleich? Ich verstehe immer noch nicht, worauf du hinauswillst.
                        Laut ISO/IEC 14882 ist ein Objekt:

                        1.8 The C+ + object model [intro.object]
                        The constructs in a C + + program create, destroy, refer to, access, and manipulate objects. An object is a
                        region of storage. [Note: A function is not an object, regardless of whether or not it occupies storage in the
                        way that objects do. ] An object is created by a definition (3.1), by a new-expression (5.3.4) or by the
                        implementation (12.2) when needed. The properties of an object are determined when the object is created.
                        An object can have a name (clause 3). An object has a storage duration (3.7) which influences its lifetime
                        (3.8). An object has a type (3.9). The term object type refers to the type with which the object is created.

                        Gruß unknown

                  2. Hallo,

                    Ich würde wegen der direkten Beziehung beides durchgehen lassen und daher auch die Aussage "eine Variable ist auch ein Objekt" hinnehmen.
                    wenn Du diesen Gedanken weiterführst kommst Du aber spätestens bei dynamisch erzeugten Objekten in Erklärungsnöte.

                    überhaupt nicht. Denn wenn ich sage "Eine Variable ist ein Objekt", dann folgt daraus ja nicht zwangsläufig, dass jedes Objekt auch eine Variable ist. Nicht jede Aussage ist umkehrbar eindeutig!

                    das in dieser Zeile
                       new QLabel();
                    erzeugte Objekt würdest Du sicher nicht als Variable bezeichnen.

                    Nein. Da wird ein Objekt erzeugt (sowohl im Sinn der Speicherverwaltung, als auch im Sinn der OOP). Aber dieses Objekt ist mit keinem Namen, keinem Bezeichner verknüpft und daher keine Variable. Es ist ja nach seiner Erzeugung nicht einmal mehr ansprechbar!

                    QLabel label;
                    und
                      QLabel *label;
                    sind Variablen.

                    Ja, eindeutig.

                    Die enthaltenen Werte können geändert werden.
                    Ändern sich dadurch die Variablen? - Ich glaube, die Antwort darauf trennt uns.

                    Nein, es ändern sich nur die Variablenwerte.

                    Ich würde diese Frage mit NEIN beantworten.

                    Siehste, so unterschiedlich liegen wir doch gar nicht.

                    Wenn Du das hier betrachtest
                      int x = 5;
                      int y = 5;
                    kämst Du doch sicher nicht auf den Gedanken zu sagen x und y sind die gleichen Variablen.

                    Nein, natürlich nicht. Es sind zwei verschiedene Variablen (verschiedener Speicherplatz, verschiedene Namen), die den gleichen Typ haben und zufällig den gleichen Wert bekommen.

                    Worauf du jetzt mit deinen Ausführungen eigentlich hinaus willst, bleibt mir aber auch verborgen.

                    So long,
                     Martin

                    --
                    Ich liebe Politiker auf Wahlplakaten.
                    Sie sind tragbar, geräuschlos, und leicht wieder zu entfernen.
                      (Loriot, deutscher Satiriker)
                    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                    1. Hallo Martin,

                      überhaupt nicht. Denn wenn ich sage "Eine Variable ist ein Objekt", dann folgt daraus ja nicht zwangsläufig, dass jedes Objekt auch eine Variable ist. Nicht jede Aussage ist umkehrbar eindeutig!

                      Ich glaube aus dem gleichen Grund wie Du nicht sagen würdest ein Objekt ist eine Variable, kann ich nicht sagen eine Variable ist ein Objekt, es sind einfach verschiedene Dinge.

                      das in dieser Zeile
                         new QLabel();
                      erzeugte Objekt würdest Du sicher nicht als Variable bezeichnen.

                      Nein. Da wird ein Objekt erzeugt (sowohl im Sinn der Speicherverwaltung, als auch im Sinn der OOP). Aber dieses Objekt ist mit keinem Namen, keinem Bezeichner verknüpft und daher keine Variable. Es ist ja nach seiner Erzeugung nicht einmal mehr ansprechbar!

                      Ansprechbar ist es schon z.B.

                      (new QLabel()).DoSomething();

                      würde funktionieren. Der Compiler greift dabei direkt auf das Rückgaberegister zu. Jedenfalls sind wir uns einig, dass das ein Objekt ist.

                      Nein, es ändern sich nur die Variablenwerte.

                      Ich würde diese Frage mit NEIN beantworten.

                      Siehste, so unterschiedlich liegen wir doch gar nicht.

                      Wenn Du das hier betrachtest
                        int x = 5;
                        int y = 5;
                      kämst Du doch sicher nicht auf den Gedanken zu sagen x und y sind die gleichen Variablen.

                      Nein, natürlich nicht. Es sind zwei verschiedene Variablen (verschiedener Speicherplatz, verschiedene Namen), die den gleichen Typ haben und zufällig den gleichen Wert bekommen.

                      Worauf du jetzt mit deinen Ausführungen eigentlich hinaus willst, bleibt mir aber auch verborgen.

                      Ich wollte darauf hinaus, dass eine Variable nicht mit ihrem Wert gleichgesetzt werden kann.

                      Nun ja, vielleicht sollten wir es einfach dabei bewenden lassen, dass wir unterschiedliche Ansichten haben.

                      MfG

                      1. Hi,

                        new QLabel();
                        Aber dieses Objekt ist mit keinem Namen, keinem Bezeichner verknüpft und daher keine Variable. Es ist ja nach seiner Erzeugung nicht einmal mehr ansprechbar!
                        Ansprechbar ist es schon z.B.
                        (new QLabel()).DoSomething();

                        okay, an eine solche Konstruktion hatte ich auch gedacht; das ist aber nicht mehr dein ursprüngliches Beispiel. Ich dachte, du hättest eine derartige Erweiterung bewusst weggelassen.

                        Jedenfalls sind wir uns einig, dass das ein Objekt ist.

                        Ja.

                        int x = 5;
                          int y = 5;
                        Es sind zwei verschiedene Variablen (verschiedener Speicherplatz, verschiedene Namen), die den gleichen Typ haben und zufällig den gleichen Wert bekommen.
                        Ich wollte darauf hinaus, dass eine Variable nicht mit ihrem Wert gleichgesetzt werden kann.

                        Das ist ja klar. Nicht mit ihrem Wert, sondern nur mit dem Speicherplatz, den sie repräsentiert, und dem Typ, als der der Speicherinhalt interpretiert wird.

                        Nun ja, vielleicht sollten wir es einfach dabei bewenden lassen, dass wir unterschiedliche Ansichten haben.

                        Haben wir? Ich habe jetzt noch weniger den Eindruck als heute früh, als ich mich in den Thread eingeklinkt habe.

                        Ciao,
                         Martin

                        --
                        Vielseitigkeit: Von vielen Dingen keine Ahnung haben.
                        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                        1. Hallo Martin,

                          ich glaube Du hast Recht. Wir liegen gar nicht so weit auseinander.
                          Es bieten sich meiner Meinung nach zwei Betrachtungsweisen für

                          QLabel label;

                          1. Der belegte Speicherplatz ist ein Objekt mit einem Namen, Typ und Speicherort. Also eine unveränderbare Instanz (im Sinne von Speicherort). Das würde dem Begriff Variable (variabler Wert) keinen Raum bieten, es sei denn ich biege den Sinn des Wortes Variable auf die Member des Objekts um.

                          2. Der belegte Speicherplatz ist eine Variable mit Name und Typ, die ein Objekt als Wert enthält. In diesem Fall wäre der Wert der Variablen als austauschbar zu sehen und könnte in keinem Fall mit dem Objekt gleichgesetzt werden, da ein Objekt eine eindeutige Instanz (im Sinne von Speicherort) sein sollte (wie ich Meine).

                          Für mich stellt es sich bei beiden Betrachtungsweisen so dar, dass ich die Begriffe Objekt und Variable nicht gleichzeitig anwenden kann, da im Endeffekt ein Objekt eine feste Speicherposition hat (im Augenblick der Betrachtung), eine Variable jedoch die Möglichkeit des Wertwechsels voraussetzt.

                          Vielleicht bin ich ja hier auch der einzige der damit ein Problem hat, dann werde ich wohl damit leben müssen.

                          MfG

                          1. Hi,

                            1. Der belegte Speicherplatz ist eine Variable mit Name und Typ, die ein Objekt als Wert enthält.

                            das ist ungefähr meine Sichtweise. Genauer:
                              Objekt   = Speicherinhalt, mit dem das Programm arbeitet
                              Variable = Name für ein Objekt eines bestimmten Typs

                            In diesem Fall wäre der Wert der Variablen als austauschbar zu sehen

                            Genau.

                            und könnte in keinem Fall mit dem Objekt gleichgesetzt werden, da ein Objekt eine eindeutige Instanz (im Sinne von Speicherort) sein sollte (wie ich Meine).

                            Das ist dieselbe Spitzfindigkeit, als wenn ich auf ein Foto zeige und sage: "Das ist meine Schwester." Natürlich ist es nur ein Bild meiner Schwester, aber diesen Unterschied macht normalerweise niemand.
                            Ebenso ist die Variable natürlich strenggenommen nur der benannte Speicherplatz für ein Objekt. Trotzdem halte ich es für eine zulässige sprachliche Vereinfachung zu sagen: Eine Variable *ist* ein Objekt (repräsentiert ein Objekt).

                            Für mich stellt es sich bei beiden Betrachtungsweisen so dar, dass ich die Begriffe Objekt und Variable nicht gleichzeitig anwenden kann, da im Endeffekt ein Objekt eine feste Speicherposition hat (im Augenblick der Betrachtung), eine Variable jedoch die Möglichkeit des Wertwechsels voraussetzt.

                            Das ist für mich kein Widerspruch, wie das folgende, wenig sinnvolle Codebeispiel zeigt:

                            float anteil = 0.381;

                            Ich habe nun ein Objekt vom Typ float, das an einer bestimmten (für den Programmierer idR nicht relevanten) Stelle im Speicher liegt. Die Variable "anteil" repräsentiert dieses Objekt und seinen Wert.

                            anteil = 2.2;

                            Nun habe ich dem Objekt (der Variablen) einen neuen Wert zugewiesen. Seine Position im Speicher und sein Typ ist unverändert, aber sein Wert ist verändert. Ist das nicht genau das, was du mit dem oben zitierten Satz ausgeschlossen hast? Oder verstehe ich immer noch nicht, was du eigentlich meinst?

                            Ciao,
                             Martin

                            --
                            Der Gast geht solange zum Tresen, bis er bricht.
                            Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
                            1. Hallo,

                              Das ist dieselbe Spitzfindigkeit, als wenn ich auf ein Foto zeige und sage: "Das ist meine Schwester." Natürlich ist es nur ein Bild meiner Schwester, aber diesen Unterschied macht normalerweise niemand.

                              Diesen Unterschied finde ich aber sehr wichtig! Schließlich kann man Objekte auf zwei Arten vergleichen:
                              1. Verweisgleichheit
                              2. Wertgleichheit

                              Ebenso ist die Variable natürlich strenggenommen nur der benannte Speicherplatz für ein Objekt. Trotzdem halte ich es für eine zulässige sprachliche Vereinfachung zu sagen: Eine Variable *ist* ein Objekt (repräsentiert ein Objekt).

                              Das ist für mich kein Widerspruch, wie das folgende, wenig sinnvolle Codebeispiel zeigt:

                              float anteil = 0.381;

                              Ich habe nun ein Objekt vom Typ float, das an einer bestimmten (für den Programmierer idR nicht relevanten) Stelle im Speicher liegt. Die Variable "anteil" repräsentiert dieses Objekt und seinen Wert.

                              anteil = 2.2;

                              Nun habe ich dem Objekt (der Variablen) einen neuen Wert zugewiesen. Seine Position im Speicher und sein Typ ist unverändert, aber sein Wert ist verändert. Ist das nicht genau das, was du mit dem oben zitierten Satz ausgeschlossen hast? Oder verstehe ich immer noch nicht, was du eigentlich meinst?

                              Genau da ist mein Problem. Für mich ist der Wert "2.2" quasi das "Objekt", das in der Variablen anteil gespeichert wird. Andersherum hieße es ja das du über die Variable anteil in das Objekt eingreifst und dessen Werte änderst.
                              Bei so einem einfachen Beispiel kann man sich das ja noch irgendwie zurechtlegen aber was wird denn aus den Objekt-Methoden und geschützten Membern. Das wären ja dann nach dieser Denke Member der Variablen. Wenn ich das Objekt in dieser Hierarchie weglasse muss ich sagen, die Variable greift auf ihren Member DoSomething zu. Finde nur ich das unpassend?

                              Sicher kann man sich darauf einigen lokale Variablen und Objekte als ein und dasselbe zu behandeln, aber wenn man alle Blickwinkel und Möglichkeiten bei der Programmierung beachtet kommt man meiner Meinung nach nicht umhin saubere und eindeutige Formulierungen zu verwenden. Und das heißt für mich das eine Variable nicht das gleiche ist wie ein Objekt.

                              MfG

                              1. Hallo,

                                ich glaube Du hast Recht. Wir liegen gar nicht so weit auseinander.
                                Es bieten sich meiner Meinung nach zwei Betrachtungsweisen für

                                QLabel label;

                                1. Der belegte Speicherplatz ist ein Objekt mit einem Namen, Typ und Speicherort. Also eine unveränderbare Instanz (im Sinne von Speicherort).

                                Ja, so ist es ja auch (in etwa). Der Speicherort ist fest. &label liefert über die gesammte Lebensdauer des Objektes den selben Wert. Die Instanz ist doch deswegen aber noch lange nicht unveränderbar. Dann wäre es eine Konstante und ich sehe dort kein const. Den Speicherbereich, welchen die Variable repräsentiert kann man verändern, einen oder mehrere veränderte Werte setzen.

                                Diesen Unterschied finde ich aber sehr wichtig! Schließlich kann man Objekte auf zwei Arten vergleichen:

                                1. Verweisgleichheit
                                2. Wertgleichheit

                                Das sind aber 2 Verschiedene Sache.
                                int a = 5;
                                int b = 5;
                                int* pA = &a;
                                int* pB = &b;
                                a == b vergleicht die Objekte a und b.
                                pA == pB vergleicht die Objekte pA und pB.
                                Einmal werden Objekte vom Typ int und das andere mal Objekte vom Typ int* verglichen.

                                Ebenso ist die Variable natürlich strenggenommen nur der benannte Speicherplatz für ein Objekt. Trotzdem halte ich es für eine zulässige sprachliche Vereinfachung zu sagen: Eine Variable *ist* ein Objekt (repräsentiert ein Objekt).

                                Eine Variable ist im Gegensatz zur Konstante ein veränderbares Objekt.

                                Genau da ist mein Problem. Für mich ist der Wert "2.2" quasi das "Objekt", das in der Variablen anteil gespeichert wird. Andersherum hieße es ja das du über die Variable anteil in das Objekt eingreifst und dessen Werte änderst.

                                Ja.

                                Bei so einem einfachen Beispiel kann man sich das ja noch irgendwie zurechtlegen aber was wird denn aus den Objekt-Methoden und geschützten Membern. Das wären ja dann nach dieser Denke Member der Variablen. Wenn ich das Objekt in dieser Hierarchie weglasse muss ich sagen, die Variable greift auf ihren Member DoSomething zu. Finde nur ich das unpassend?

                                Ich jedenfalls nicht.

                                Sicher kann man sich darauf einigen lokale Variablen und Objekte als ein und dasselbe zu behandeln, aber wenn man alle Blickwinkel und Möglichkeiten bei der Programmierung beachtet kommt man meiner Meinung nach nicht umhin saubere und eindeutige Formulierungen zu verwenden. Und das heißt für mich das eine Variable nicht das gleiche ist wie ein Objekt.

                                Ist ja auch nicht ganz das Gleiche. Eine Variable ist ein veränderbares Objekt.

      2. Wo(/Von wem) werden Objekte als "automatische Variablen" bezeichnet?

        Der Bjarne Stroustrup macht das z. B. so. Weiterhin ist auch Wikipedia der Meinung, obwohl man das ja eigentlich nicht zitieren darf:
        Static variables
        Automatic variables

        Falls Du ganz auf Nummer Sicher gehen willst, gibt es auch noch den C-Standard, dort siehe Kapitel 6.2.4.

        Man sollte zwischen statischer Speicherzuweisung und dem Schlüsselwort 'static' unterscheiden. Beide haben gar nichts miteinander zu tun.

        In C oder C++ werden mit dem Keyword 'static' entweder statische lokale Variablen, statische Membervariablen oder statische globale Variablen angelegt. Die Gemeinsamkeit ist in allen Fällen, dass deren reservierter Speicherbereich während eines Programmlaufs gleich bleibt. Insofern ist das Keyword 'static' kennzeichnend für die Definition statischer Speicherobjekte bzw. statischer Variablen.

        Was eine "statische Speicherzuweisung" sein soll, weiß ich allerdings nicht.

        MfG

        Andreas

        1. Hello,

          In C oder C++ werden mit dem Keyword 'static' entweder statische lokale Variablen, statische Membervariablen oder statische globale Variablen angelegt. Die Gemeinsamkeit ist in allen Fällen, dass deren reservierter Speicherbereich während eines Programmlaufs gleich bleibt. Insofern ist das Keyword 'static' kennzeichnend für die Definition statischer Speicherobjekte bzw. statischer Variablen.

          Was eine "statische Speicherzuweisung" sein soll, weiß ich allerdings nicht.

          Die Zuweisung liegt im Datensegment des Programmes.

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
        2. Hallo,

          Du merkst gar nicht worauf ich hinaus will!

          dass Objekte, die mit
          Qlabel label;
          erzeugt werden, auch als "automatische Variablen" bezeichnet werden

          Genau, _automatische_ Objekte werden automatisch zerstört... ;)

          Mich stört Deine Gleichsetzung von Object und Variable.
          Ein Objekt ist keine Variable und eine Variable ist kein Objekt und sie werden auch nicht so genannt oder würdest du in dieser Zeile

          int x = 5;

          "5" als Variable bezeichnen.

          Was eine "statische Speicherzuweisung" sein soll, weiß ich allerdings nicht.

          Statische Speicherverwaltung (-verwaltung, -zuweisung ist nicht ganz korrekt) ist ein verbreiteter Oberbegriff für die nichtdynamische Speicherverwaltung. Der Speicherbedarf und -struktur werden zur Kompilierzeit unveränderbar (statisch) festgelegt. Wenn Du mal im Inet suchst wirst du in verschiedenen Publikationen fündig werden.

          MfG

          1. Ein Objekt ist keine Variable und eine Variable ist kein Objekt und sie werden auch nicht so genannt [...]

            Das hattest Du jetzt schon mehrfach in diesem Thread wiederholt. Ursprünglich ging es ja um "Stack vs. Heap". Um dem Nebenzweig "Objekt vs. Variable" etwas mehr Leben einzuhauchen, würde ich vorschlagen, dass Du hier mal präzise postest, was Du als Variable und was Du als Objekt bezeichnest.

            [...] oder würdest du in dieser Zeile
            int x = 5;

            "5" als Variable bezeichnen.

            An dieser Stelle würde ich die "5" eher als Literal oder als Token bezeichnen. Das "x" wäre ebenfalls ein als Variablenname interpretierbares Token, dies hat aber nur für den Betrachter des Quellcodes oder für den Compiler Relevanz. Im Binary gibt es nur noch den Variablen-Inhalt, d. h. die (inzwischen binärcodierte) "5" sowie Speicheradressen oder Stack-Offsets. Schreibt man dagegen eine Zeile

            new x(5);

            wird die Speicheradresse nicht mit ins Binary codiert und ist zunächst nicht leicht zugänglich. Der Speicherplatz existiert aber trotzdem, wenn man irgendwie die Speicheradresse erraten könnte, würde man wieder auf den Inhalt "5" zugreifen können.

            Eine Google- und Wikipedia-Suche nach "Objekt" führt mal wieder auf eine ISO-Norm:

            **object**
            region of data storage in the execution environment, the contents of which can represent values
            Note: When referenced, an object may be interpreted as having a particular type; see 6.3.2.1
            – ISO/IEC 9899:1999: §3.14 (siehe Wikipedia-Seite über "Objekt")

            Jetzt würde ich gerne von Dir lesen, inwiefern sich "Variablen" von diesem Konzept maßgeblich unterscheiden.

            Viele Grüße

            Andreas

            1. new x(5);

              Bevor Proteste kommen, ich meinte natürlich sowas wie

              new int(5);

              MfG

              Andreas

            2. Das hattest Du jetzt schon mehrfach in diesem Thread wiederholt. Ursprünglich ging es ja um "Stack vs. Heap". Um dem Nebenzweig "Objekt vs. Variable" etwas mehr Leben einzuhauchen, würde ich vorschlagen, dass Du hier mal präzise postest, was Du als Variable und was Du als Objekt bezeichnest.

              Ich vermute er wollte auf soetwas hinaus.

            3. Hallo Andreas,

              ich denke was mich stört ist, dass eine Variable ein Speichplatz, ein Platzhalter ist, der Objekte enthält und den Zugriff auf das Objekt ermöglicht, während ein Objekt eine Entität, ein Ding, ein Wert ist.
              Jedenfalls sollte man beide nicht gleichsetzen.

              Im übrigen ist das Thema durch, nenn es wie Du willst. Offenbar bin ich der einzige der sich daran stört. Wir hatten gestern schon eine längere Diskussion. Mehr habe ich dazu nicht zu sagen.

              MfG

              P.S. Vielleicht programmiere ich ja in einer VOT (Variablen Orientierten Programmiersprache) ;)