<?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[Merkwürdiges Programmverhalten bei Array als Funktionsargument]]></title><description><![CDATA[<p>Es geht um folgendes Programm, dass eine Klasse für ein zweidimensionales Array von bool-Werten implementieren soll und durch zwei Klammeroperatoren einen Zugriff auf ein beliebiges Element array[i][j] erlauben soll. Dabei soll der erste Klammeroperator ein Objekt der Klasse RowProxy zurückliefern, dieses repräsentiert die Zeile i. Aus diesem Objekt wird dann mittels des zweiten Klammeroperators auf das j-te Element zugegriffen.</p>
<pre><code>#include &lt;iostream&gt;

/* Der Zugriff auf das zweidimens. Array erfolgt anders als beim
gewöhnlichen Array, da die Indizierung bei (1,1) beginnt:
TwoDBoolArray[i][j] liefert den j-ten Eintrag in der i-ten Zeile.
*/

// ein Objekt das vom operator[] zurueckgegeben wird
class RowProxy
{

public:
// Konstruktor
RowProxy(const bool* const daten, int zeilenindex, int spaltenzahl );
// der &quot;innere&quot; Klammerzugriffsoperator
bool operator [](int j );
bool* _daten;

int Zeilenindex;
int Spaltenzahl;
private: 
};

/* erzeugt eine &quot;Zeile&quot; vom Index Zeilenindex aus der Matrix 
mithilfe der linearen Daten, indem bis zum Feld (Index - 1) *
* Spaltenzahl gegangen wird (erstes Feld der gesuchten Zeile),
dann werden von dort beginnend alle Zeilenelemente in ein array
_daten geschrieben. */
RowProxy::RowProxy (const bool* const Daten, int zeilenindex, int spaltenzahl)
{
   bool array[spaltenzahl];
   for (int i = 0; i &lt; spaltenzahl; i = i + 1)
   {
      array[i] = Daten[((zeilenindex - 1) * spaltenzahl) + i];
   }
   _daten = array;
   Zeilenindex = zeilenindex;
   Spaltenzahl = spaltenzahl;    
}

/* liefert das j-te Element der Zeile */
bool RowProxy::operator[](int j)
{
   return _daten[j-1];
}

class TwoDBoolArray
{

public:

// Initialisiere ein n x m Array
TwoDBoolArray( int n, int m);
// Copy-Konstruktor
TwoDBoolArray(const TwoDBoolArray&amp; other );
// Destruktor
~TwoDBoolArray();
// Zuweisungsoperator
TwoDBoolArray&amp; operator=(const TwoDBoolArray&amp; other );
// Gebe Zeilenzahl zurueck
int rows();
// Gebe Spaltenzahl zurueck
int cols();
// der &quot;aeussere&quot; Klammerzugriffsoperator
RowProxy operator[](int i );
bool* daten; 
int m, n;
private: 
 // Array, das alle m*n Daten linear speichert.
 // m Spaltenzahl, n Zeilenzahl

};

// ------------------------------------------------

TwoDBoolArray::TwoDBoolArray( int N, int M)
{
   bool Array[N*M];
   for (int i = 0; i &lt; N * M; i = i + 1)
   {
      Array[i] = true;
   }
   daten = Array;
   m = M;
   n = N;
}

TwoDBoolArray::~TwoDBoolArray()
{
}

TwoDBoolArray::TwoDBoolArray(const TwoDBoolArray&amp; other )
{
   n = other.n;
   m = other.m;
   bool Array[n*m];
   for (int i = 0; i &lt; n * m; i = i + 1)
   {
      Array[i] = other.daten[i];
   }
   daten = Array;
}

TwoDBoolArray&amp; TwoDBoolArray::operator=(const TwoDBoolArray&amp; other )
{
   n = other.n;
   m = other.m;
   bool Array[n*m];
   for (int i = 0; i &lt; n * m; i = i + 1)
   {
      Array[i] = other.daten[i];
   }
   daten = Array;
}

int TwoDBoolArray::rows()
{
   return n;
}

int TwoDBoolArray::cols()
{
   return m;
}

RowProxy TwoDBoolArray::operator[](int i )
{
   RowProxy Row(daten, i, m);
   return Row;
}

//------------------------------------------

int main()
{

   TwoDBoolArray array(3, 5);
   std::cout &lt;&lt; array[2][3] &lt;&lt; std::endl;
}
</code></pre>
<p>Der Code kompiliert und wird auch ohne Fehlermeldung ausgeführt. Allerdings wird als Ergebnis 0 ausgegeben und nicht, wie zu erwarten, 1. Durch den debugger konnte ich das Problem schon recht gut eingrenzen. Es scheint an dem Konstruktor von Row im ersten Klammeroperator zu liegen. Lässt man sich auf dem Debugger Schritt für Schritt die Werte ausgeben, so sieht man, dass die Initilisierung noch funktioniert. Bevor der Konstruktor im ersten Klammeroperator ausgeführt wird, ist daten ein Array mit 15 true-Einträgen. Sobald aber der Operator aufgerufen wird (aber noch bevor irgendetwas in seinem Rumpf ausgeführt wird), ist daten auf einmal verändert worden. Hier, was der debugger sagt:</p>
<p>Breakpoint 1, main () at <a href="http://2DArray.cc:141" rel="nofollow">2DArray.cc:141</a><br />
141 TwoDBoolArray array(3, 5);<br />
(gdb) next<br />
142 std::cout &lt;&lt; array[2][3] &lt;&lt; std::endl;<br />
(gdb) print array.daten<br />
$1 = (bool <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="😉"
    /> 0xbffff130<br />
(gdb) print array.daten[0]<br />
$2 = true<br />
(gdb) print array.daten[14]<br />
$3 = true<br />
(gdb) step<br />
TwoDBoolArray::operator[] (this=0xbffff178, i=2) at <a href="http://2DArray.cc:132" rel="nofollow">2DArray.cc:132</a><br />
132 RowProxy Row(daten, i, m);<br />
(gdb) print array.daten<br />
No symbol &quot;array&quot; in current context.<br />
(gdb) print daten<br />
$4 = (bool <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="😉"
    /> 0xbffff130<br />
(gdb) print daten[3]<br />
$5 = true<br />
(gdb) step<br />
RowProxy::RowProxy (this=0xbffff184, Daten=0xbffff130, zeilenindex=2,<br />
spaltenzahl=5) at <a href="http://2DArray.cc:32" rel="nofollow">2DArray.cc:32</a><br />
32 bool array[spaltenzahl];<br />
(gdb) print daten<br />
No symbol &quot;daten&quot; in current context.<br />
(gdb) print Daten<br />
$6 = (const bool * const) 0xbffff130<br />
(gdb) print Daten[0]<br />
$7 = false<br />
(gdb) print Daten[14]<br />
$8 = 4</p>
<p>Woran das liegt, kann ich mir aber nicht erklären. Um Hilfe wäre ich sehr dankbar.</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/336057/merkwürdiges-programmverhalten-bei-array-als-funktionsargument</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 21:16:24 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/336057.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 30 Dec 2015 23:06:45 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Merkwürdiges Programmverhalten bei Array als Funktionsargument on Wed, 30 Dec 2015 23:06:45 GMT]]></title><description><![CDATA[<p>Es geht um folgendes Programm, dass eine Klasse für ein zweidimensionales Array von bool-Werten implementieren soll und durch zwei Klammeroperatoren einen Zugriff auf ein beliebiges Element array[i][j] erlauben soll. Dabei soll der erste Klammeroperator ein Objekt der Klasse RowProxy zurückliefern, dieses repräsentiert die Zeile i. Aus diesem Objekt wird dann mittels des zweiten Klammeroperators auf das j-te Element zugegriffen.</p>
<pre><code>#include &lt;iostream&gt;

/* Der Zugriff auf das zweidimens. Array erfolgt anders als beim
gewöhnlichen Array, da die Indizierung bei (1,1) beginnt:
TwoDBoolArray[i][j] liefert den j-ten Eintrag in der i-ten Zeile.
*/

// ein Objekt das vom operator[] zurueckgegeben wird
class RowProxy
{

public:
// Konstruktor
RowProxy(const bool* const daten, int zeilenindex, int spaltenzahl );
// der &quot;innere&quot; Klammerzugriffsoperator
bool operator [](int j );
bool* _daten;

int Zeilenindex;
int Spaltenzahl;
private: 
};

/* erzeugt eine &quot;Zeile&quot; vom Index Zeilenindex aus der Matrix 
mithilfe der linearen Daten, indem bis zum Feld (Index - 1) *
* Spaltenzahl gegangen wird (erstes Feld der gesuchten Zeile),
dann werden von dort beginnend alle Zeilenelemente in ein array
_daten geschrieben. */
RowProxy::RowProxy (const bool* const Daten, int zeilenindex, int spaltenzahl)
{
   bool array[spaltenzahl];
   for (int i = 0; i &lt; spaltenzahl; i = i + 1)
   {
      array[i] = Daten[((zeilenindex - 1) * spaltenzahl) + i];
   }
   _daten = array;
   Zeilenindex = zeilenindex;
   Spaltenzahl = spaltenzahl;    
}

/* liefert das j-te Element der Zeile */
bool RowProxy::operator[](int j)
{
   return _daten[j-1];
}

class TwoDBoolArray
{

public:

// Initialisiere ein n x m Array
TwoDBoolArray( int n, int m);
// Copy-Konstruktor
TwoDBoolArray(const TwoDBoolArray&amp; other );
// Destruktor
~TwoDBoolArray();
// Zuweisungsoperator
TwoDBoolArray&amp; operator=(const TwoDBoolArray&amp; other );
// Gebe Zeilenzahl zurueck
int rows();
// Gebe Spaltenzahl zurueck
int cols();
// der &quot;aeussere&quot; Klammerzugriffsoperator
RowProxy operator[](int i );
bool* daten; 
int m, n;
private: 
 // Array, das alle m*n Daten linear speichert.
 // m Spaltenzahl, n Zeilenzahl

};

// ------------------------------------------------

TwoDBoolArray::TwoDBoolArray( int N, int M)
{
   bool Array[N*M];
   for (int i = 0; i &lt; N * M; i = i + 1)
   {
      Array[i] = true;
   }
   daten = Array;
   m = M;
   n = N;
}

TwoDBoolArray::~TwoDBoolArray()
{
}

TwoDBoolArray::TwoDBoolArray(const TwoDBoolArray&amp; other )
{
   n = other.n;
   m = other.m;
   bool Array[n*m];
   for (int i = 0; i &lt; n * m; i = i + 1)
   {
      Array[i] = other.daten[i];
   }
   daten = Array;
}

TwoDBoolArray&amp; TwoDBoolArray::operator=(const TwoDBoolArray&amp; other )
{
   n = other.n;
   m = other.m;
   bool Array[n*m];
   for (int i = 0; i &lt; n * m; i = i + 1)
   {
      Array[i] = other.daten[i];
   }
   daten = Array;
}

int TwoDBoolArray::rows()
{
   return n;
}

int TwoDBoolArray::cols()
{
   return m;
}

RowProxy TwoDBoolArray::operator[](int i )
{
   RowProxy Row(daten, i, m);
   return Row;
}

//------------------------------------------

int main()
{

   TwoDBoolArray array(3, 5);
   std::cout &lt;&lt; array[2][3] &lt;&lt; std::endl;
}
</code></pre>
<p>Der Code kompiliert und wird auch ohne Fehlermeldung ausgeführt. Allerdings wird als Ergebnis 0 ausgegeben und nicht, wie zu erwarten, 1. Durch den debugger konnte ich das Problem schon recht gut eingrenzen. Es scheint an dem Konstruktor von Row im ersten Klammeroperator zu liegen. Lässt man sich auf dem Debugger Schritt für Schritt die Werte ausgeben, so sieht man, dass die Initilisierung noch funktioniert. Bevor der Konstruktor im ersten Klammeroperator ausgeführt wird, ist daten ein Array mit 15 true-Einträgen. Sobald aber der Operator aufgerufen wird (aber noch bevor irgendetwas in seinem Rumpf ausgeführt wird), ist daten auf einmal verändert worden. Hier, was der debugger sagt:</p>
<p>Breakpoint 1, main () at <a href="http://2DArray.cc:141" rel="nofollow">2DArray.cc:141</a><br />
141 TwoDBoolArray array(3, 5);<br />
(gdb) next<br />
142 std::cout &lt;&lt; array[2][3] &lt;&lt; std::endl;<br />
(gdb) print array.daten<br />
$1 = (bool <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="😉"
    /> 0xbffff130<br />
(gdb) print array.daten[0]<br />
$2 = true<br />
(gdb) print array.daten[14]<br />
$3 = true<br />
(gdb) step<br />
TwoDBoolArray::operator[] (this=0xbffff178, i=2) at <a href="http://2DArray.cc:132" rel="nofollow">2DArray.cc:132</a><br />
132 RowProxy Row(daten, i, m);<br />
(gdb) print array.daten<br />
No symbol &quot;array&quot; in current context.<br />
(gdb) print daten<br />
$4 = (bool <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="😉"
    /> 0xbffff130<br />
(gdb) print daten[3]<br />
$5 = true<br />
(gdb) step<br />
RowProxy::RowProxy (this=0xbffff184, Daten=0xbffff130, zeilenindex=2,<br />
spaltenzahl=5) at <a href="http://2DArray.cc:32" rel="nofollow">2DArray.cc:32</a><br />
32 bool array[spaltenzahl];<br />
(gdb) print daten<br />
No symbol &quot;daten&quot; in current context.<br />
(gdb) print Daten<br />
$6 = (const bool * const) 0xbffff130<br />
(gdb) print Daten[0]<br />
$7 = false<br />
(gdb) print Daten[14]<br />
$8 = 4</p>
<p>Woran das liegt, kann ich mir aber nicht erklären. Um Hilfe wäre ich sehr dankbar.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2481191</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2481191</guid><dc:creator><![CDATA[*Elias* 0]]></dc:creator><pubDate>Wed, 30 Dec 2015 23:06:45 GMT</pubDate></item><item><title><![CDATA[Reply to Merkwürdiges Programmverhalten bei Array als Funktionsargument on Wed, 30 Dec 2015 23:24:46 GMT]]></title><description><![CDATA[<pre><code>bool Array[N*M];
// ...
daten = Array;
</code></pre>
<p>So erstellt man kein Array und lässt eine Membervariable darauf zeigen. Erstens sind N und M Parameter und die Größe des Arrays daher keine Konstante. Sowas nennt sich Variable Length Array und gibt es eigentlich nur in C, aber nicht in C++ (Ich tippe du nutzt GCC, compilier mal mit -pedantic). Zweitens lässt du deinen daten Pointer auf eine lokale Variable zeigen. Nachdem der Constructor fertig ist zeigt der Pointer auf Speicher der nicht mehr dir gehört. Schau dir mal <code>std::vector</code> an*. Damit kannst du einfacher dynamische Arrays nutzen.</p>
<p>*Beachte, dass es eine Spezialisierung für <code>vector&lt;bool&gt;</code> gibt die nur 1 Bit pro Wert braucht. Das klingt zwar toll, sorgt aber für viele komische Eigenheiten von <code>vector&lt;bool&gt;</code> . Nehm lieber <code>vector&lt;unsigned char&gt;</code> , auch wenn du nur true oder false speichern willst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2481197</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2481197</guid><dc:creator><![CDATA[sebi707]]></dc:creator><pubDate>Wed, 30 Dec 2015 23:24:46 GMT</pubDate></item><item><title><![CDATA[Reply to Merkwürdiges Programmverhalten bei Array als Funktionsargument on Wed, 30 Dec 2015 23:25:39 GMT]]></title><description><![CDATA[<p>Lokale Variablen sind nach dem Ende des Skopes nicht mehr gültig, dü leakst sie aber mehr als einmal:</p>
<pre><code>RowProxy::RowProxy (const bool* const Daten, int zeilenindex, int spaltenzahl)
{
   bool array[spaltenzahl];
   for (int i = 0; i &lt; spaltenzahl; i = i + 1)
   {
      array[i] = Daten[((zeilenindex - 1) * spaltenzahl) + i];
   }
   _daten = array; //Böse
   Zeilenindex = zeilenindex;
   Spaltenzahl = spaltenzahl;    
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2481198</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2481198</guid><dc:creator><![CDATA[DarkShadow44]]></dc:creator><pubDate>Wed, 30 Dec 2015 23:25:39 GMT</pubDate></item></channel></rss>