grossmutter: C/C++; Zeigt Zeiger auf ein Array?

Hallo,

folgendes Problem;

  
int main(int argc, char** argv)  
{  
 char* p1 = (char*)NULL;  
 char* p2 = (char*)NULL;  
 char* _p1 = new char;  
 char* _p2 = new char[1024];  
  
 for(;(false);) {  
  short c = 0;  
  
  cout << "[1, 2]: \t";  
  
  cin >> c;  
  
  if(c == 1) {  
   p1 = _p1;  
   p2 = _p2;  
  } else if(c == 2) {  
   p2 = _p1;  
   p1 = _p2;  
  } else {  
   cout << "Du hast eine falsche Eingabe gemacht.\n";  
   return EXIT_FAILURE;  
  }  
  _p1 = (char*)NULL;  
  _p2 = (char*)NULL;  
  c = 0;  
  break;  
 }  
  
 /*  
  
 ...  
  
 */  
  
 if(p1 != (char*)NULL) {  
  delete p1;  
  p1 = (char*)NULL;  
 }  
  
 if(p2 != (char*)NULL) {  
  delete p2;  
  p2 = (char*)NULL;  
 }  
  
 return EXIT_SUCCESS;  
}  

Dieser Code ist sehr konstruiert und theoretisch.

Die for-Schleife habe ich nur geschrieben weil die Variable c danach nicht mehr verfügbar ist. Wird zwar eh auf 0 gesetzt, also die Eingabe ist weg, aber so wird es noch deutlicher.
Ich weis danach eben nicht was p1 und was p2 ist. (ob Array oder nicht)

Das eigentliche Problem das ich ansprechen möchte ist, das ich nicht weis ob ich ein Array löschen muss vom Heap oder eine einzelne Variable.
Kann man irgendwie in Erfahrung bringen ob p1+1 auch zu p1 gehört?

Weil wenn p1 auf eine einzelne Variable zeigt. Und ich p1+1 auch zu löschen versuche, geht das mächtig in die Hose.

Also ich fürchte mal das es nicht möglich ist? Habe ich recht?

Eure Grossmutter.

  1. Dieser Code ist sehr konstruiert und theoretisch.

    In der Tat; deshalb gehe ich darauf auch gar nicht ein.

    std::vector, std::string, std::stringstream

    könnten Dir weiterhelfen.

    Grüsse

    Solkar

    P.S.:

    Eure Grossmutter.

    Gewiss nicht.

    1. Also das finde ich jetzt absolut nicht hilfreich.
      Zeiger und STL ist ja dann schon ein bisschen was anderes nicht?

      Kann man anhand eines gegebenen Zeigers (void* p;), der auf eine Adresse im Heap verweist erkennen ob es ein Element *p[1] gibt?

      Das ist alles was ich wissen will, und die STL ist mir sehr wohl bekannt aber hilft mir bei meinem Problem absolut nicht weiter.

      Eure Grossmutter

      1. Also das finde ich jetzt absolut nicht hilfreich.

        Hilfe fällt halt manchmal etwas anders aus als erwartet.

        Zeiger und STL ist ja dann schon ein bisschen was anderes nicht?

        Ja, zum Glück ist das so.
        Genau deshalb hab ich Dir die STL empfohlen.

        [...]

        Grüsse

        Solkar

  2. Hello,

    Dieser Code ist sehr konstruiert und theoretisch.

    Die for-Schleife habe ich nur geschrieben weil die Variable c danach nicht mehr verfügbar ist.

    mMn läuft die so auch gar nicht, da Du die Laufbedingung auf 'false' gesetzt hast.

    Wird zwar eh auf 0 gesetzt, also die Eingabe ist weg, aber so wird es noch deutlicher.
    Ich weis danach eben nicht was p1 und was p2 ist. (ob Array oder nicht)

    Nur den Fall für c==1 betrachtet,
    Ich vermute, dass Du folgendes erreichen wolltest:

    p1 sollte danach eine Kopie des Pointers _p1 sein
      p2 sollte danach eine Kopie des Pointers _p2 sein

    ABER, versuche mal:

    int* a;
        char* z;

    cout << "a*: " << a << endl;
        cout << "z*: " << z << endl;

    und mach Dir Deinen Reim darauf.
    C++ ist eben doch sehr geheimnisvoll chaotisch.

    Ich habe versucht, das alles nachzuvollziehen. Brauche ja schließlich auch noch etwas Übung :-)
    Was sollte denn eigentlich passieren? Vielleicht beschreibst Du mal, was Du vor hattest.

    char* _p1 = new char;
     char* _p2 = new char[1024];

    *_p2 = 'H';
     *(_p2+1) = 'a';
     *(_p2+2) = 'l';
     *(_p2+3) = 'l';
     *(_p2+4) = 'o';
     *(_p2+1000) = '\0';

    cout << "_p2: " << _p2 << endl;
            cout << "_p2: " << *_p2 << endl;

    Liebe Grüße aus Syburg bei Dortmund

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Was sollte denn eigentlich passieren? Vielleicht beschreibst Du mal, was Du vor hattest.

      Das habe ich doch schon bereits 2 mal getan. War das nicht deutlich oder deutsch genug?

      Aber Ok. Ich erzähls gern noch mal.

        
        
      void delete(void* p)  
      {  
       if(p == (void*)NULL) {  
        return;  
       }  
       if(p == ARRAY) {  
        delete[] p;  
       } else if(p != ARRAY) {  
        delete p;  
       }  
       p = (void*)NULL;  
      }  
        
      int main(int argc, char** argv)  
      {  
       void* p1 = new void[1024];  
       void* p2 = new void;  
        
       delete(p1);  
       delete(p2);  
        
       return EXIT_SUCCESS;  
      }  
      
      

      Wird das Problem somit deutlicher?
      Es geht mir nur darum, von einem beliebigen Zeiger mit beliebgen Typ in Erfahrung zu bringen ob es sich dabei um ein Array handelt. Das Programm darf aber nicht abstürzen.

      Eure Grossmutter

      1. Hello,

        Was sollte denn eigentlich passieren? Vielleicht beschreibst Du mal, was Du vor hattest.

        Das habe ich doch schon bereits 2 mal getan. War das nicht deutlich oder deutsch genug?

        if(p == ARRAY) {

        Wird das Problem somit deutlicher?
        Es geht mir nur darum, von einem beliebigen Zeiger mit beliebgen Typ in Erfahrung zu bringen ob es sich dabei um ein Array handelt. Das Programm darf aber nicht abstürzen.

        Bist Du sicher, dass Du in C++ programmieren willst und nicht vielleicht in PHP?

        Zeiger tragen keine Information darüber, ob sie auf ein Array eines Typs zeigen, oder nur auf ein Element des Typs. Genaugenommen zeigen sie immer nur auf ein Element, bei einem Array eben auf das erste.

        #include <iostream>

        using namespace std;

        int main(int argc, char* argv[])
        {
            int* a;
            char* z = {"hallo Grossmutter"};
            char* y;

        y = z;

        char* p1 = (char*)NULL;   // hier wird ein Zeiger auf eine Char-Array erzeugt,
                                      // dessen erste vier Bytes dann mit dem Wert von NULL
                                      // überschrieben werden. Es wird also NICHT der Zeiger
                                      // überschrieben!
                                      // Intel-32-Plattform vorausgesetzt!
            char* p2 = (char*)NULL;   // hier das Gleiche

        char* p3 = "Hallo neue Welt";  // hier wird ein Array mit dem Inhalt "Hallo ..."
                                           // angelegt und ein Zeiger darauf erzeugt

        char* _p1 = new char;     // hier wird ein Zeiger auf einen Char im Heap erzeugt
                                      // was im Char drinsteht ist ungewiss.
            char* _p2 = new char[1024]; // hier wird ein Zeiger auf ein Char-Array auf dem Heap
            char* _p4 = new char[1024]; // erzeugt

        *_p2 = 'H';
         *(_p2+1) = 'a';       // Hier werden einzelne Elemente des Arrays auf dem Heap
         *(_p2+2) = 'l';       // verändert
         *(_p2+3) = 'l';
         *(_p2+4) = 'o';
         *(_p2+1000) = '\0';

        short c = 0;

        cout << "p3: " << p3 << endl;
            cout << "p3[11]: " << p3[11] << endl;
            cout << "p3+1: " << p3+1 << endl;

        cout << "c: " << c << endl;

        //    cout << *p1 << endl;      // das ist verboten, weil p1 ein Zeiger auf ein Char-Array
                                        // ist und du die ersten vier Bytes davon mit NULL überschrieben
                                        // hast. Wenn Du p1 mit cout ausgeben würdest, würde nichts aus-
                                        // gegeben werden, weil NULL hier vermutlich 0000 ist, worauf man
                                        // sich aber nicht bei jeder Plattform verlassen kann.
                                        // NULL kann auch eine fiktive Adresse enthalten!
                                        // wenn Du nun *p1 ausgeben lässt, dann wird (fälschlicherweise)
                                        // versucht, auszugeben, worauf das zeigt, was dort steht,
                                        // worauf p1 zeigt, also hier, worauf 0000 zeigt.
                                        // das ist aber verboten, weil es nicht zu Deinem Speicherbereich
                                        // gehört.

        // cout << p2 << endl;     // warum hier "Ende" ist, habe ich nch nicht ergründet.

        cout << "_p2: " << _p2 << endl;
            cout << "*_p2: " << *_p2 << endl;
            cout << "*p2[1]: " << _p2[1] << endl;

        cout << "_p4: " << _p4 << endl;
            cout << "_p4: " << *_p4 << endl;

        cout << "a*: " << a << endl;
            cout << "z*: " << z << endl;
            cout << "y*: " << y << endl;

        return EXIT_SUCCESS;
        }

        Probier es nochmal aus.
        Und denke auch daran, dass in cout die Operatoren überladen sind und sich der Stream deshalb bei jedem übergebenen Datentyp anders verhalten kann.

        Liebe Grüße aus Syburg bei Dortmund

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Hi,

          Zeiger tragen keine Information darüber, ob sie auf ein Array eines Typs zeigen, oder nur auf ein Element des Typs. Genaugenommen zeigen sie immer nur auf ein Element, bei einem Array eben auf das erste.

          Wenn man es genau nimmt stimmt das so nicht.
          Du kannst bei einfachen Zeigern nicht sagen, ob sie auf Elemente in einem Array zeigen, oder auf einzelne Variablen. Das war wohl das was du meintest.
          Der name des Arrays ist übrigens auch nur ein konstanter Zeiger.

          Ein 2-Dim-Array ist nichts anderes als Zeiger auf Arrays.
          Beispiel:
          int matrix[5][5];                // 2-Dim-Feld mit 5 Zeilen und 5 Spalten
          *matrix oder matrix[0]           // Zeiger auf 1. Zeile (Zeile = Feld mit 5 Elementen)
          *(matrix+1) oder matrix[1]       // Zeiger auf 2. Zeile

          mfG,
          steckl

    2. Was sollte denn eigentlich passieren? Vielleicht beschreibst Du mal, was Du vor hattest.

      Das habe ich doch schon bereits 2 mal getan. War das nicht deutlich oder deutsch genug?

      Aber Ok. Ich erzähls gern noch mal.

      void delete(void* p)
      {
       if(p == (void*)NULL) {
        return;
       }
       if(p == ARRAY) {
        delete[] p;
       } else if(p != ARRAY) {
        delete p;
       }
       p = (void*)NULL;
      }

      int main(int argc, char** argv)
      {
       char* p1 = new char[1024];
       char* p2 = new char;

      delete((void*)p1);
       delete((void*)p2);

      return EXIT_SUCCESS;
      }

      Wird das Problem somit deutlicher?
      Es geht mir nur darum, von einem beliebigen Zeiger mit beliebgen Typ in Erfahrung zu bringen ob es sich dabei um ein Array handelt. Das Programm darf aber nicht abstürzen.

      Eure Grossmutter

      1. Hallo,

        Es geht mir nur darum, von einem beliebigen Zeiger mit beliebgen Typ in Erfahrung zu bringen ob es sich dabei um ein Array handelt.

        Kurze Antwort: Das geht in C++ nicht.

        Lange Antwort: Wenn Du Dich in die Speicherverwaltung einklinkst (Stichworte "operator new" und "operator delete"), dann könntest Du diese Information zusätzlich mitspeichern und beim Löschen berücksichtigen. Allerdings: In der C++-Speicherverwaltung rumpfuschen sollte man nur, wenn man *wirklich* *wirklich* weiß, was man tut, da man sehr schnell auf sehr unerwartete Probleme stoßen kann, siehe http://www.scs.cs.nyu.edu/~dm/c++-new.html.

        Viele Grüße,
        Christian