Frage

Ich versuche dynamisch zuzuweisen (es ist nicht so dynamisch wie jetzt, aber irgendwann wird es sein) Speicher für Objekte in einem sehr Einfaches C ++ - Programm. Ich bin neu im Unterricht und habe erst kürzlich angefangen, mit C ++ zu spielen und C zurückzulassen. Hier ist der Code:

#include <iostream>
using namespace std;

class Test {
  private:
    int i;
  public:
    Test(int);
    ~Test();
    void print();
};

Test::Test(int ii) { i = ii; }
Test::~Test() { i=0; cout << "deconstructor called...value of i= " << i << endl; }
void Test::print() { cout << "value of i= " << i << endl; }

int main()
{
  Test a(10),*b,*c;
  //a.print(); // this works

  b = new Test(12);
  //b->print(); // this works as well

  for (int i=0; i<2; i++)
    c = new Test(i);

  c->print(); /* this shows that the value of i=1 .. should be 0? */
  c[0].print(); /* as expected (I guess), this prints i=1 as well... [expected because c->print() shows i=1 also */
  c[1].print(); /* shows value of i=0... */

  //delete []c; /* this fails miserably, but `delete c` works, why :( */

}

Ein Großteil meiner Verwirrung ist tatsächlich in Kommentaren im Code selbst enthalten. Ich versuche im Grunde ein Array zu haben c wo jedes Element des Arrays ein Objekt von sich selbst ist.

Das Verhalten des Code, den ich bekomme, wird in den Kommentaren beschrieben.

War es hilfreich?

Lösung

Vielleicht sollten wir uns die Erklärungen ansehen, die Sie erweitert haben: Sie haben:

Test a(10);
Test *b;
Test *c;

Sie haben B und C als Zeiger-zu-Test definiert, aber Sie möchten, dass C eine Reihe von Zeiger zu Tests ist. Die Erklärung für C, die Sie beabsichtigten, war wahrscheinlich:

Test **c;

was Sie initialisieren würden:

c = new Test*[2];

for (int i=0; i<2; i++)
   c[i] = new Test(i);

und auf die Sie also zugreifen würden:

c[0]->print();
c[1]->print();

Andere Tipps

Es gibt nur wenige ernsthafte Probleme mit dem angegebenen Code.

  1. Leistung new an *b aber vermisst zu delete es.
  2. Sie überschreiben *c Ein paar Male in for Schleife, die den Speicher verlässt. Verwenden Sie immer Ressourcen, bevor Sie einen neuen von einem Zeiger ausweisen.
  3. Wenn Sie mit zuweisen new/new[]/malloc Dann müssen Sie den Zeiger mit damit umgehen delete/delete[]/free beziehungsweise. Das gleiche gilt nicht mit *c (Deshalb scheitert es).

Abgesehen von der dynamischen Allokation von Lernen sollte man auch STL -Container bewusst sein, die eine bessere Möglichkeit für den Umgang mit dynamischen Ressourcen bieten. z.B std :: vector.

for (int i=0; i<2; i++)
    c = new Test(i);

Der obige Code läuft den Speicher. c Zeigen Sie einfach auf das zuletzt konstruierte Objekt in der Loop -Iteration.

c-> print (); /* Dies zeigt, dass der Wert von i = 1 .. 0 sein sollte?

Hier c Punkte auf den Ort aufgebaut new Test(1);. Also die Ausgabe.

Jeder Neu[ sollte begleitet werden mit löschen[ und Neu mit löschen. Sie können beides nicht einschränken.

Dass die delete[] Funktioniert nicht ganz normal: Sie haben C C als Array nie zugeteilt, sondern als Zeiger. Sie könnten die Adresse eines Arrays in einem Zeiger speichern, aber das ist alles. Ich frage mich tatsächlich, warum genau C [1] funktioniert, weil Sie for Loop speichert nur wiederholt Zeiger auf neu zugewiesene Objekte im selben Zeiger (Sie bevölkern kein Array!).

delete c[];Nur lösches Startelement. Wenn Sie das Array -Gebrauch löschen möchten dz delete c[] in für Schleife

Sie haben es nicht geschafft, Speicher für C zuzuweisen und immer wieder zu kodieren. Wie können Sie eine Ausgabe erhalten, ohne eine Zeigervariable Speicher zuzuweisen?

Sehen Sie nach mir, Sie haben Speicher für *C mehrmals als vergeben

for (int i=0; i<2; i++)
c = new Test(i);

Schauen Sie sich diesen Code an, was alles klar macht

for (int i=0; i<2; i++)
{   c = new Test(i);    }       /*see , here the loop goes for i=0; then
                                for i=1; which basically overwrites what c will have
                                 i.e. finally       c = new test(1); */
c->print(); /* works fine , gives value of i=1 */
c[0].print(); /* as expected , this prints i=1 as well... */
c[1].print(); /*clearly, it will give a garbage value */
delete c;

Aber meiner Meinung nach wäre es in Ordnung, ersetzt zu ersetzen

for (int i=0; i<2; i++)
{   c = new Test(i);    }

mit

c = new Test(1);    //as the previous code is doing the same in for loop but that was consuming more resources

Also, wenn Sie ausgeben möchten, wie i = 0 und dann i = 1, dann tun Sie es-

c = new int(0);
c->print(); /* works fine , gives value of i=0 */
c[0].print(); /* as expected , this prints i=0 as well... */
delete c;

c = new int(1);
c->print(); /* works fine , gives value of i=1 */
c[0].print(); /* as expected , this prints i=1 as well... */
delete c;

Der obige Code ist das, was Ihr Bedürfnis vollständig erfüllt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top