<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Einsatz von new]]></title><description><![CDATA[<p>Servus,</p>
<p>ich hab mit new immer wieder so meine Probleme und würde mich auf ein paar Antworten eurerseits.</p>
<p>Folgendes Beispiel funktioniert ohne Probleme im VC (ohne Optimierungen) und das wirft ein paar Fragen auf.</p>
<p>Meines Kennissestandes:</p>
<ul>
<li>new reserviert im Heap einen Speicherplatz</li>
<li>der Heap lebt solange, wie der aktuelle Prozess lebt</li>
<li>mittels &quot;Test t&quot; wird der Speicherplatz im Stack angelegt und beim Verlassen der Funktion wieder freigegeben</li>
</ul>
<p>Wieso sind dann die Zahlen 5 und 2 noch vorhanden? Nach dem Verlassen des Konstruktors sollte der Speicher wieder freigegeben werden, oder?<br />
Gibt es eine Ausnahme für sogenannte Primitive-Daten (z.B. int, long, float, double, ....)?</p>
<p>Die Fragen sind etwas trivial, aber ich kann aus den Bücher &amp; Co. nicht entnehmen, wann ich genau new benutzen muss und wann nicht. Ich bitte nur denen auf diese Frage zu antworten, die es ernst meinen. Auf Weisheiten ala Dro...el kann ich verzichten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<pre><code class="language-cpp">#import &lt;iostream&gt;

using std::cout;

class Abc {

private:
  int zahl;

public:
  Abc();
  ~Abc();

  int getZahl();
};

Abc::Abc() {
  this-&gt;zahl = 5;
}

Abc::~Abc() {}

int Abc::getZahl() { return this-&gt;zahl; }

class Test {

private:
  Abc ab;
  int cnt;

public:
  Test();
  ~Test();

  Abc* getAbc();
  int getCnt();
};

Test::Test() {
  //this-&gt;ab = new Abc();
  this-&gt;cnt = 2;
}

Test::~Test() {
  //delete this-&gt;ab;
}

Abc* Test::getAbc() {
  return &amp;this-&gt;ab;
}

int Test::getCnt() {
  return this-&gt;cnt;
}

int main() {
  Test t;

  cout &lt;&lt; &quot;Test.cnt: &quot;;
  cout &lt;&lt; t.getCnt();

  cout &lt;&lt; &quot;\n&quot;;

  cout &lt;&lt; &quot;Abc.zahl: &quot;;
  cout &lt;&lt; t.getZahl()-&gt;getZahl();
}

// Ausgabe erfolgreich. Ohne jegliche Fehler
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/240031/einsatz-von-new</link><generator>RSS for Node</generator><lastBuildDate>Tue, 22 Sep 2026 05:30:35 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/240031.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 30 Apr 2009 18:51:30 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Einsatz von new on Thu, 30 Apr 2009 18:51:30 GMT]]></title><description><![CDATA[<p>Servus,</p>
<p>ich hab mit new immer wieder so meine Probleme und würde mich auf ein paar Antworten eurerseits.</p>
<p>Folgendes Beispiel funktioniert ohne Probleme im VC (ohne Optimierungen) und das wirft ein paar Fragen auf.</p>
<p>Meines Kennissestandes:</p>
<ul>
<li>new reserviert im Heap einen Speicherplatz</li>
<li>der Heap lebt solange, wie der aktuelle Prozess lebt</li>
<li>mittels &quot;Test t&quot; wird der Speicherplatz im Stack angelegt und beim Verlassen der Funktion wieder freigegeben</li>
</ul>
<p>Wieso sind dann die Zahlen 5 und 2 noch vorhanden? Nach dem Verlassen des Konstruktors sollte der Speicher wieder freigegeben werden, oder?<br />
Gibt es eine Ausnahme für sogenannte Primitive-Daten (z.B. int, long, float, double, ....)?</p>
<p>Die Fragen sind etwas trivial, aber ich kann aus den Bücher &amp; Co. nicht entnehmen, wann ich genau new benutzen muss und wann nicht. Ich bitte nur denen auf diese Frage zu antworten, die es ernst meinen. Auf Weisheiten ala Dro...el kann ich verzichten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<pre><code class="language-cpp">#import &lt;iostream&gt;

using std::cout;

class Abc {

private:
  int zahl;

public:
  Abc();
  ~Abc();

  int getZahl();
};

Abc::Abc() {
  this-&gt;zahl = 5;
}

Abc::~Abc() {}

int Abc::getZahl() { return this-&gt;zahl; }

class Test {

private:
  Abc ab;
  int cnt;

public:
  Test();
  ~Test();

  Abc* getAbc();
  int getCnt();
};

Test::Test() {
  //this-&gt;ab = new Abc();
  this-&gt;cnt = 2;
}

Test::~Test() {
  //delete this-&gt;ab;
}

Abc* Test::getAbc() {
  return &amp;this-&gt;ab;
}

int Test::getCnt() {
  return this-&gt;cnt;
}

int main() {
  Test t;

  cout &lt;&lt; &quot;Test.cnt: &quot;;
  cout &lt;&lt; t.getCnt();

  cout &lt;&lt; &quot;\n&quot;;

  cout &lt;&lt; &quot;Abc.zahl: &quot;;
  cout &lt;&lt; t.getZahl()-&gt;getZahl();
}

// Ausgabe erfolgreich. Ohne jegliche Fehler
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1703845</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703845</guid><dc:creator><![CDATA[Siassei]]></dc:creator><pubDate>Thu, 30 Apr 2009 18:51:30 GMT</pubDate></item><item><title><![CDATA[Reply to Einsatz von new on Thu, 30 Apr 2009 19:59:49 GMT]]></title><description><![CDATA[<p>Siassei schrieb:</p>
<blockquote>
<p>Wieso sind dann die Zahlen 5 und 2 noch vorhanden? Nach dem Verlassen des Konstruktors sollte der Speicher wieder freigegeben werden, oder?</p>
</blockquote>
<p>Nein, da das Objekt t noch existiert, und du Membervariablen einsetzt. Letztere werden auch mit dem Objekt freigegeben.</p>
<p>Gehen wir mal einige Fälle durch:</p>
<p>a) Lokale, nichtstatische Variablen<br />
Lokale Variablen werden lokal deklariert und gelten von diesem Punkt aus, bis zum verlassen des jeweiligen &quot;Scopes&quot;</p>
<pre><code class="language-cpp">int foo()
{   // &lt;-- Hier beginnt ein Scope
    int a = 4;
    {   // &lt;-- Hier beginnt ein Scope
        int b = 2;
    }   // &lt;-- Hier endet der innere Scope (b wird ungültig)
    return a; // Durch return wird auch das Scope verlassen
}             //     (a wird ungültig, eine Kopie zurückgegeben [*])
</code></pre>
<p>* Tatsächlich kann es sein, das ein Compiler einige Kopien wegoptimieren kann.</p>
<p>b) Nicht-Statische Membervariablen<br />
Membervariablen gelten für die Lebensdauer des Objektes</p>
<pre><code class="language-cpp">class Bar
{
    private:
        int a; // Deklaration innerhalb der Klasse, nicht in einer Funktion!

    public:
        Bar()
        {
            a = 4; // Hier wird a geändert, a ist Objektweit gültig
            int b = 2;
        }   // b wird hier ungültig, da lokale Variable, a existiert aber weiter

        ~Bar()
        {
        }   // Hier wird a tatsächlich ungültig

        int GetA() const
        {
            return a; // Hier wird a zurückgegeben
        }
};

int main()
{
    Bar bar; // Hier wird ein Objekt angelegt, der Konstruktor aufgerufen
    bar.GetA(); // Gültig, da Objekt noch existiert
}   // Hier wird bar ungültig, damit auch bar.a
</code></pre>
<p>c) Undefiniertes Verhalten (Anmerkung)<br />
Nun gehen wir einen Schritt weiter: Ungültig werden, heißt nicht das die Werte sofert aus dem Speicher entfernt werden - Nur können sie jederzeit überschrieben werden, der Zugriff ist also undefiniert.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

int main()
{
    int *pa = 0;
    {
        int a = 4;
        pa = &amp;a; // pa zeigt nun auf den Speicherbereich von a
    }   // a wird ungültig...
    std::cout &lt;&lt; *pa; // ... was nun im Speicher an der Stelle steht ist
    // undefiniert, hier ist die Wahrscheinlichkeit aber noch recht hoch
    // das tatsächlich noch 4 ausgegeben wird. Aber wie gesagt ungültig.
}
</code></pre>
<p>d) statische lokale Variablen/statische Membervariablen<br />
Statische Variablen sind eine Besonderheit. Statische lokale Variablen werden beim ersten Aufruf angelegt, bleiben aber bis zum Programmende gültig, und behalten ihren Wert</p>
<pre><code class="language-cpp">void foo()
{
    static int a = 1; // Beim ersten Aufruf wird a angelegt, und mit 1 initialisiert.
    a += 2; // Pro durchgang wird a um 2 erhöht
    std::cout &lt;&lt; a; // Beim ersten Durchgang 3, beim zweiten 5...
}
</code></pre>
<p>Statische Membervariablen werden spätestens mit der ersten Instanz der Klasse (oder dem ersten Zugriff, was eher erfolgt) angelegt. Und gelten im Gegensatz zu nicht statischen Membervariablen Klassenweit (statt Objektweit). Am besten ist dies Am Beispiel zu erklären:</p>
<pre><code class="language-cpp">// Header
#ifndef BAR_HEADER
#define BAR_HEADER

class Bar {
    static int a;
    int b;

    // Hier zeige ich noch eine Besonderheit, erkläre ich weiter unten
    Bar(int b);
};

#endif
</code></pre>
<pre><code class="language-cpp">// Source
#include &quot;Bar.h&quot;

int Bar::a = 0; // Statischen Member Bar::a einmalig initialisieren (Merkwürdige
                // schreibweise, ich weiß

// Das int b in der Parameterliste ist ein anderes als die Membervariable,
// es &quot;verdeckt&quot; es...
Bar::Bar(int b) // Der Parameter gilt Methodenweit (wie eine lokale Variable)
{
    b += 2; // Hiermit erhöhe ich den Parameter, nicht die Membervariable
    this-&gt;b = b; // Über this-&gt; greife ich auf die Membervariable zu

    ++a; // Hiermit erhöhe ich die Statische Membervariable um 1.
}
</code></pre>
<pre><code class="language-cpp">// main.cpp
#include &lt;iostream&gt;
#include &quot;Bar.h&quot;

int main()
{
    std::cout &lt;&lt; Bar::a &lt;&lt; std::endl; // Statische Membervariablen kann ich 
                                      // auch ohne Objekt ansprechen
    // Ausgabe: 0

    Bar bar1(4);
    std::cout &lt;&lt; bar1.a &lt;&lt; &quot;, &quot; &lt;&lt; bar1.b &lt;&lt; &quot;, &quot; &lt;&lt; Bar::a &lt;&lt; std::endl;
    // Ausgabe: 1, 6, 1
    Bar bar2(10);
    std::cout &lt;&lt; bar2.a &lt;&lt; &quot;, &quot; &lt;&lt; bar2.b &lt;&lt; &quot;, &quot; &lt;&lt; Bar::a &lt;&lt; std::endl;
    // Ausgabe: 2, 12, 2

    // Ausgabe: 2, 2, 2 (Den es handelt sich um EINE Variable [Klassenweit])
    std::cout &lt;&lt; bar1.a &lt;&lt; &quot;, &quot; &lt;&lt; bar2.a &lt;&lt; &quot;, &quot; &lt;&lt; Bar::a;
    // Ausgabe: 6, 12 (Den es handelt sich um unterschiedliche Variablen [Da Objektweit]
    std::cout &lt;&lt; bar1.b &lt;&lt; &quot;, &quot; &lt;&lt; bar2.b;
}
</code></pre>
<p>e) new/delete... Zeiger und auf Heap allozierten Speicher</p>
<p>Erzeugen wir erst einmal ein Speicherleak</p>
<pre><code class="language-cpp">int main()
{
    {
        // Dynamisches allozieren von Speicher, ein Int wird auf den Heap
        // abgelegt, die Adresse wird pa zugewiesen.
        int *pa = new int(4);
    }   // pa wird ungültig...
    // ... aber der Speicher bleibt alloziert! ==&gt; Speicherleak
}
</code></pre>
<p>Es wurde hier eine lokale Variable angelegt pa, die auf einen Speicherbereich mit einem int-Wert verweist.</p>
<pre><code>( Stack )     ( Heap )
 [Adresse] --&gt; [int: 4]
  int* pa
</code></pre>
<p>Die lokale Variable wird aber am Ende des Scopes ungültig, der Speicherbereich wurde aber nicht freigegeben.</p>
<pre><code>( Heap )
 [int: 4]
</code></pre>
<p>Zu jedem new gehört ein delete, zu jedem new[] ein delete[]</p>
<pre><code class="language-cpp">int main()
{   // [1.]
    int *pa = 0;          // pa wird angelegt und die Adresse mit 0 initialisiert [2.]
    pa = new int(4);      // Speicher auf dem Heap wird alloziert [3.]
    delete pa;            // Der Speicher auf dem Heap wird freigegeben, [4.]
                          //    pa existiert aber weiterhin
}   // &lt;-- Hier wird pa ungültig [5.]
</code></pre>
<p>Noch mal im Einzelschritt (Nehmen wir mal als Adresse des allozierten Speichers 0xA6F0 an...):</p>
<pre><code>___________________       ________________
    |      Stack      |       |     Heap     |

1.            -                       -
2.   int * pa = 0x0000  --x           -
3.         pa = 0xA6F0  ----&gt;     (int) 4
4.         pa = 0xA6F0  ----&gt;    undefiniert    [undefiniert: da freigegeben]
5.            -                       -
</code></pre>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1703866</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703866</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Thu, 30 Apr 2009 19:59:49 GMT</pubDate></item><item><title><![CDATA[Reply to Einsatz von new on Thu, 30 Apr 2009 20:53:38 GMT]]></title><description><![CDATA[<p>Servus André,</p>
<p>tausend Dank für deinen Beitrag, der hat die letzten Unsicherheiten ausgelöscht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Noch kurz eine Bestätigung. Folgendes ist somit undefiniert</p>
<pre><code class="language-cpp">// main.cpp
#include &lt;iostream&gt;
#include &quot;Bar.h&quot;

int main()
{
    std::cout &lt;&lt; Bar::a &lt;&lt; std::endl; // Statische Membervariablen kann ich
                                      // auch ohne Objekt ansprechen
    // Ausgabe: 0

    Bar bar1(4);
    std::cout &lt;&lt; bar1.a &lt;&lt; &quot;, &quot; &lt;&lt; bar1.b &lt;&lt; &quot;, &quot; &lt;&lt; Bar::a &lt;&lt; std::endl;
    // Ausgabe: 1, 6, 1
    Bar bar2(10);
    std::cout &lt;&lt; bar2.a &lt;&lt; &quot;, &quot; &lt;&lt; bar2.b &lt;&lt; &quot;, &quot; &lt;&lt; Bar::a &lt;&lt; std::endl;
    // Ausgabe: 2, 12, 2

    // Ausgabe: 2, 2, 2 (Den es handelt sich um EINE Variable [Klassenweit])
    std::cout &lt;&lt; bar1.a &lt;&lt; &quot;, &quot; &lt;&lt; bar2.a &lt;&lt; &quot;, &quot; &lt;&lt; Bar::a;
    // Ausgabe: 6, 12 (Den es handelt sich um unterschiedliche Variablen [Da Objektweit]
    std::cout &lt;&lt; bar1.b &lt;&lt; &quot;, &quot; &lt;&lt; bar2.b;

    Bar bar3(6);
    {
        Bar bar4(8);
        bar3.setA(&amp;bar4.a); // Klasse Bar erweitert: void setA(int* a) { this-&gt;a = *a; }
    }// bar4 wird ungültig

    std::cout &lt;&lt; bar4.a // undefiniert, wahrscheinlich 8
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1703896</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703896</guid><dc:creator><![CDATA[Siassei]]></dc:creator><pubDate>Thu, 30 Apr 2009 20:53:38 GMT</pubDate></item><item><title><![CDATA[Reply to Einsatz von new on Thu, 30 Apr 2009 22:07:46 GMT]]></title><description><![CDATA[<p>Siassei schrieb:</p>
<blockquote>
<pre><code class="language-cpp">Bar bar3(6);
    {
        Bar bar4(8);
        bar3.setA(&amp;bar4.a); // Klasse Bar erweitert: void setA(int* a) { this-&gt;a = *a; }
    }// bar4 wird ungültig

    std::cout &lt;&lt; bar4.a // undefiniert, wahrscheinlich 8
}
</code></pre>
</blockquote>
<p>Kompiliert nicht, da bar4 mit der schließenden Klammer out of scope ging und es im umschließenden scope keinen Bezeichner &quot;bar4&quot; gibt.<br />
Wenn du eigentlich sagen wolltest</p>
<pre><code class="language-cpp">std::cout &lt;&lt; bar3.a &lt;&lt; std::endl;
</code></pre>
<p>dann stimmt die Annahme, daß es undefiniert nicht, weil du in Bar::setA(int *a) den Pointer dereferenziert hast (*a), womit du den Wert nach this-&gt;a <strong>kopierst</strong>.</p>
<p>Undefiniertes Verhalten wäre eher sowas:</p>
<pre><code class="language-cpp">class Bar {
//...
  int *a;
//...
  void printA() {
    std::cout &lt;&lt; *(this-&gt;a) &lt;&lt; std::endl;
  }
  void setA(int *a) {
    this-&gt;a = a;
  }
//...
};

//...
  Bar bar3(6);
  {
    Bar bar4(8);
    bar3.setA(&amp;bar4.a);
  }
  bar3.printA(); // Ausgabe ist undefiniert, gibt aber wahrscheinlich 8 aus.
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1703916</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703916</guid><dc:creator><![CDATA[miep]]></dc:creator><pubDate>Thu, 30 Apr 2009 22:07:46 GMT</pubDate></item><item><title><![CDATA[Reply to Einsatz von new on Thu, 30 Apr 2009 23:26:48 GMT]]></title><description><![CDATA[<p>Vielleicht solltest du noch den Unterschied zwischen Wert, Zeiger und Referenz kennen lernen. Betrachten wir erstmal die ersten Beiden.</p>
<p>Grundsätzlich stellt die Deklaration einer Variablen irgendwo im Speicher Platz bereit (Bezüglich Referenzen kann man dies nicht ganz eindeutig sagen, daher später mehr dazu).</p>
<p>Das heißt, das im folgenden Code...</p>
<pre><code class="language-cpp">int a = 4;
int b = 5;
int *pa = &amp;a;
int *pb = &amp;b;
</code></pre>
<p>4 Plätze im Speicher bereit. Die ersten Beiden sind groß genug um jeweils einen Int-Wert, die Letzten beiden um eine Adresse eines Int-Wertes aufnehmen zu können.</p>
<p>Nehmen wir mal an, das int 4 Byte belegt, und die Werte hintereinander im Speicher liegen, zudem die Adressen bei 0x10203040 beginnen:</p>
<p>Im Speicher sähe es dann etwa wie folgt aus (was erst einmal verwirrt)<br />
... 00 00 00 04 00 00 00 05 10 20 30 40 10 20 30 40 ...</p>
<p>Drösseln wir das wieder auf:</p>
<pre><code>Startposition  Inhalt       Erklärung      Variablenname
im Speicher                                (nur im Code)*

0x10203040     0x00000004   Wert 4         a
0x10203044     0x00000005   Wert 5         b
0x10203048     0x10203040   Adresse von a  pa
0x1020304C     0x10203040   Adresse von b  pb
</code></pre>
<p>* Der Variablenname existiert im laufenden Programm nirgends, und dient nur im Code als Bezeichner - Sprich als Hilfsmittel um es den Programmierer verständlich zu machen.</p>
<p>So, was passiert wenn du nun schreibst?</p>
<pre><code class="language-cpp">a = b;
pa = pb;
</code></pre>
<p>Konkret wird der Inhalt kopiert:</p>
<pre><code>Startposition  Inhalt       Erklärung      Variablenname
im Speicher                                (nur im Code)*

0x10203040     0x00000004   Wert 4         a
0x10203044     0x00000004   Wert 4         b
0x10203048     0x10203040   Adresse von a  pa
0x1020304C     0x10203040   Adresse von a  pb
</code></pre>
<p>Wie du siehst haben nun jeweils die int-Werte den gleichen Inhalt, ebenso die beiden Zeiger. Dennoch sind es eigenständige Speicherbereiche.</p>
<p>Nun gehen wir einen winzigen Schritt weiter: Das deklarieren einer Variable muss (je nach Kontext) keine automatische Initialisierung bedeuten, ggf. wird einfach das als Wert angenommen was zufälligerweise im Speicher steht. Daher solltest du Variablen möglichst immer sobald möglich initialisieren, und Zeiger die noch kein Ziel haben, mit 0 initialisieren.</p>
<pre><code class="language-cpp">// ACHTUNG NICHT NACHMACHEN!
int *pc;
delete pc;
</code></pre>
<p>Dies kann verheerende Auswirkungen haben (davon abgesehen das man nur Speicher mit delete freigeben sollte der mit new alloziert wurde), in pc kann irgendwas stehen, und delete greift versucht nun das an der Zieladresse befindliche Aufzuräumen. Glücklicherweise ist delete 0 definiert =&gt; dies führt nichts aus.</p>
<pre><code class="language-cpp">int *pc = 0;
delete pc; // Wohldefiniert (delete 0 macht nichts)
</code></pre>
<p>Nun gehen wir einen weiteren Schritt...</p>
<pre><code class="language-cpp">int * pd = new int(4);
int * pe = pd;
delete pe;
pe = 0;
delete pd; // KRASH!
</code></pre>
<p>Was haben wir hier getan? Wenn du dir das bisherige durch den Kopf gehen lässt, solltest du wissen warum dies eine Zugriffsverletzung geben kann (undefiniert). Wie wir wissen haben pd und pe einen eigenen Inhalt. Wir kopieren nun den Inhalt (die Adresse den mit new allozierten Speichers) von pd in pe (Beide zeigen auf die gleiche Adresse). Nun geben wir den Speicher an der Zieladresse auf die pe zeigt frei, und setzen pe auf 0. Da pe aber einen eigenen Inhalt hat, wird pd davon nichts mitbekommen. Sprich das delete auf pd wird versuchen den bereits freigegebenen Speicher erneut freizugeben... undefiniertes Verhalten.</p>
<p>SOOOOOOOOO, nun Referenzen...</p>
<p>Tja, was sind Referenzen...</p>
<pre><code class="language-cpp">int a = 4;
int &amp;b = a;
</code></pre>
<p>Was der Compiler hieraus hinter den Kulissen macht, kann ich nicht eindeutig sagen. Wichtig ist aber: Referenzen sind sogenannte &quot;Aliasnamen&quot;. Referenzen sind also nur ein anderer Name für eine bestehende Variable.</p>
<pre><code class="language-cpp">int a = 4;
int &amp;b = a;
b = 5; // Da b nur ein Aliasname für a ist...

std::cout &lt;&lt; a; // ... ist die Ausgabe hier nun 5!
</code></pre>
<p>Es kann sein, das der Compiler hierbei nur eine Speicheradresse verwendet, du kannst a nun unter a als auch b erreichen und ändern.</p>
<p>Damit kommen wir zum nächsten Punkt:<br />
Call-By-Value, Call-By-Referenz...</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

void foo1(int a) // Call by Value (Wertkopie)
{
    std::cout &lt;&lt; a &lt;&lt; &quot;, &quot;;
    a = 1;
    std::cout &lt;&lt; a &lt;&lt; &quot;, &quot;;
}

void foo2(int &amp; a) // Call by Referenz
{
    std::cout &lt;&lt; a &lt;&lt; &quot;, &quot;;
    a = 2;
    std::cout &lt;&lt; a &lt;&lt; &quot;, &quot;;
}

int main()
{
    int a = 0;
    std::cout &lt;&lt; a &lt;&lt; &quot;, &quot;;
    foo1(a);
    std::cout &lt;&lt; a &lt;&lt; &quot;, &quot;;
    foo2(a);
    std::cout &lt;&lt; a &lt;&lt; &quot;, &quot;;
}
</code></pre>
<p>Die Ausgabe dieses Programmes wird 0, 0, 1, 0, 0, 2, 2 sein.<br />
Wenn du nun Verstehst warum das so ist, hast du meine Ausführung schon gut verstanden.</p>
<p>Was ist wiederum mit einer Zeigerübergabe?<br />
Das kommt darauf an was du in einer Funktion veränderst. Zeiger werden wie Werte nur kopiert, Zeigen aber auf den gleichen Inhalt.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

void foo1(int * pa)
{
    std::cout &lt;&lt; *pa &lt;&lt; &quot;, &quot;; // Würde 0 ausgeben
    int b = 1;
    pa = &amp;b; // Änderungen des Zeiger-&quot;Wertes&quot; des Parameters, nicht des
    // Bereiches auf dem das Original zeigt.
    std::cout &lt;&lt; *pa &lt;&lt; &quot;, &quot;;
}

void foo2(int * pa)
{
    std::cout &lt;&lt; *pa &lt;&lt; &quot;, &quot;;
    *pa = 2; // Änderung des Wertes auf den pa zeigt, nicht der Adresse
    std::cout &lt;&lt; *pa &lt;&lt; &quot;, &quot;;
}

int main()
{
    int a = 0;
    std::cout &lt;&lt; a &lt;&lt; &quot;, &quot;;
    foo1(&amp;a);
    std::cout &lt;&lt; a &lt;&lt; &quot;, &quot;;
    foo2(&amp;a);
    std::cout &lt;&lt; a &lt;&lt; &quot;, &quot;;
}
</code></pre>
<p>Die Ausgabe wäre identisch wie oben. (Ich hoffe aufgrund meiner Müdigkeit keinen Flüchtigkeitsfehler gemacht zu haben, da ungetestet).</p>
<p>Es gibt auch Doppelzeiger int ** a; (Zeiger auf einen Int-Zeiger), Zeigerreferenzen int *&amp; a; (Referenz/Aliasname einer Int-Zeiger Variablen)... usw. Aber das führt zu weit.</p>
<p>cu André</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1703932</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703932</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Thu, 30 Apr 2009 23:26:48 GMT</pubDate></item><item><title><![CDATA[Reply to Einsatz von new on Fri, 01 May 2009 00:28:29 GMT]]></title><description><![CDATA[<p>Siassei schrieb:</p>
<blockquote>
<p>(...) die letzten Unsicherheiten (...)</p>
</blockquote>
<p>ROFL <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1703941</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1703941</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 01 May 2009 00:28:29 GMT</pubDate></item><item><title><![CDATA[Reply to Einsatz von new on Fri, 01 May 2009 12:18:13 GMT]]></title><description><![CDATA[<p>Servus,</p>
<p>man schlaft hier auch mal wer?</p>
<p>@miep Du hast natürlich Recht. Ich meinte cout &lt;&lt; bar3.a</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/14941">@asc</a></p>
<blockquote>
<p>(Ich hoffe aufgrund meiner Müdigkeit keinen Flüchtigkeitsfehler gemacht zu haben, da ungetestet).</p>
</blockquote>
<p>Der ein oder andere ist dabei, aber das macht nichts <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p><strong>Doppelzeiger:</strong></p>
<pre><code class="language-cpp">int val = 5;

size_t   *ptr  = &amp;val;  // Zeiger auf ein Element
size_t  **ptr2 = &amp;ptr;  // Zeiger auf ein Element des Zeigers ptr
size_t ***ptr3 = &amp;ptr2; // Zeiger auf ein Element des Zeigers ptr über den Zeiger ptr2
size_t ....
</code></pre>
<p><strong>Zeigerreferenzen:</strong></p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

void ptrTest(int *&amp;ptr)
{
    *ptr = new int(5);
}

int main()
{
    int *valPtr;
    ptrTest(valPtr);
    std::cout &lt;&lt; valPtr; // Adresse des Pointers
    std::cout &lt;&lt; *valPtr; // Wert des Ziels
    delete valPtr; // Speicherbereinigung
}
</code></pre>
<p>Alles ungetestet und mit dem ein oder anderem Flüchtigkeitsfehler <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Gruß,<br />
Thomas</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1704008</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1704008</guid><dc:creator><![CDATA[Siassei]]></dc:creator><pubDate>Fri, 01 May 2009 12:18:13 GMT</pubDate></item></channel></rss>