Double Pointer



  • Hey,
    ich hab da mal eine Frage zu der Benutzung von einem "double Pointer".
    Ich würde das gerne benutzen, da in einer Datei nach einem Wert suche. Dieser Wert ist nicht nur einmal dort drin. Also hab ich mir gedacht ich mach ein "Pointer Array".

    **ptr
    

    soll der Pointer sein und

    count
    

    der Index.

    struct pos{
      char **ptr;
      int  count;
    }; 
    
    void function(){   
      pos mpos;
      mpos.count = 0;
      const char* SOI;
      mpos.ptr[mpos.count] = &SOI; //Fehler
      mpos.count++;
    }
    

    Der Code läuft nicht(Pseudocode). Allerdings würde ich gerne wissen wieso sowas nicht funktioniert.(Kommentar)
    Ich würde gerne wissen, wie ich **ptr den wert von *SOI zuweisen kann. Oder mach ich hier was, was überhaupt nicht geht?



  • In deinem Beispiel forderst du gar keinen Speicher an. Wenn du ein Array willst, nimm auch eines, oder besser gleich STL-Container:

    std::vector<char*> positions;
    

    Zeiger selbst sind nur Verweise, sie bieten keinen Speicherplatz für mehrere Elemente (wie Arrays oder Container).



  • Das Array von Zeigern auf einen Zeiger musst Du schon noch initialisieren. Intern ist ein Zeiger auch nur eine Zahl. Und würdest Du erwarten, dass:

    int* array;
    array[5] = 10;
    

    klappt?

    int** arrayOfPointers;
    // create array of 10 pointers
    arrayOfPointers = new int*[10];
    

    Unabhängig davon solltest Du den Kontext erklären, dann erhältst Du umfangreiche Tipps, wieso Du kein gutes C++ programmierst. 😉

    Edit: Tsts, zu langsam



  • Ja das macht Sinn. Allerdings sind bei mir in dem struct mehrere Pointer. D.h. so:

    struct pos{
      char *pointy;
      char *point;
      char **ptr;
    };
    

    Aber könnte ich da ich ja die Anzahl weiß einen struct in einem struct machen? Vom Prinzip so:

    struct pos{
      struct posi{
        char *ptr1;
        char *ptr2;
      };
      char *pointy;
      char *point;
    };
    

    Und kann ich das dann einfach so zuweisen:?

    void function(){   
      pos mpos;
      posi mposi;
      char *SOI;
      mposi = &SOI;
    }
    

    Da ich den struct ja einfach nach der reinfolge fühlen will?

    EDIT: Zweiten Post jetzt erst gelesen schreib ich gleich was zu.



  • Enno schrieb:

    ich hab da mal eine Frage zu der Benutzung von einem "double Pointer".

    Zeiger auf Zeiger.

    Enno schrieb:

    Ich würde das gerne benutzen, da in einer Datei nach einem Wert suche.

    Noch sehe ich keinen Zusammenhang. Aber ich finde es ernsthaft super, dass du verraten hast, welches Problem du eigentlich lösen willst.

    Enno schrieb:

    Dieser Wert ist nicht nur einmal dort drin. Also hab ich mir gedacht ich mach ein "Pointer Array".

    **ptr
    

    soll der Pointer sein und

    count
    

    der Index.

    struct pos{
      char **ptr;
      int  count;
    }; 
    
    void function(){   
      pos mpos;
      mpos.count = 0;
      const char* SOI;
      mpos.ptr[mpos.count] = &SOI; //Fehler
      mpos.count++;
    }
    

    Der Code läuft nicht(Pseudocode). Allerdings würde ich gerne wissen wieso sowas nicht funktioniert.(Kommentar)
    Ich würde gerne wissen, wie ich **ptr den wert von *SOI zuweisen kann. Oder mach ich hier was, was überhaupt nicht geht?

    Ich sehe immer noch keinen Zusammenhang zu deinem eigentlichen Problem. Die Zuweisung lässt der Compiler nicht zu, weil SOI ein Zeiger auf const-char ist und das nicht zu deiner Definition von pos::ptr passt. So oder so sehe ich aber keinen Sinn in der Aktion. Wozu sollte mpos.ptr auf SOI zeigen? Du hast auch nirgens irgendwo Speicher reserviert, auf den ptr zeigen würde.

    Hast du die Datei, die du durchsuchen willst komplett im Speicher stehen? Dann würden Zeiger ja Sinn machen. Genausogut könntest du dir natürlich auch Indizes merken. Also z.B. so:

    vector<char> lade_komplett(char const* dateiname)
    {
      ...
    }
    
    vector<ptrdiff_t> suche(vector<char> const& worin, char const* wonach)
    {
      vector<ptrdiff_t> ergebnis;
      if (!worin.empty()) {
        char const* start = &worin[0];
        char const* end = start + worin.size();
        auto wonach_len = strlen(wonach);
        for (char const* pos=start;;) {
          pos = search(pos,end,wonach,wonach+wonach_len);
          if (pos!=end) // etwas gefunden
            ergebnis.push_back(pos-start);
          else          // nichts mehr gefunden
            break;
        }
      }
      return ergebnis;
    }
    
    int main()
    {
      vector<char> inhalt = lade_komplett("soundso.dat");
      vector<ptrdiff_t> positionen = suche(inhalt,"blah");
    }
    

    (ungetestet)

    vector, search und strlen sind Dinge aus der C++ Standardbibliothek.



  • [quote="Eisflamme"]

    int** arrayOfPointers;
    // create array of 10 pointers
    arrayOfPointers = new int*[10];
    

    /quote]

    Genau das war bei mir der Fehler. Das hatte ich nicht. 🙂 Danke.

    Um euch mal ein wenig aufzuklären:
    Ich gebe dieser Funktion einen Pointer der in einem Vector mit den kompletten Daten auf den Anfangs Bereich zeigt und wie lang der Bereich ist, da ich nicht den kompletten kram brauche. In diesem Bereich suche ich nun nach den verschieden "Markern" und speicher diese in meinem struct. Keine Ahnung ob man das versteht. 😃

    void Marker::findMarker(const char* SOI, size_t length){
      MPos.DQT = new const char*[2];
      MPos.DHT = new const char*[4];
      for(unsigned int i=0; i<length; i++){
        if(SOI[i] == (char)0xff){
          i++;
          switch(SOI[i]){
            case (char)0xe0:
              MPos.APP = &SOI[i]; 
              break;
            case (char)0xdb:
              MPos.DQT[MPos.DQTcount] = &SOI[i-1];
              MPos.DQTcount++;
              break;
            case (char)0xc0:
              MPos.SOF = &SOI[i];
              break;
            case (char)0xc4:
              MPos.DHT[MPos.DHTcount] = &SOI[i];
              MPos.DHTcount++;
              break;
            case (char)0xda:
              MPos.SOS = &SOI[i];
              break;    
          }//switch
        }//if
      }//for
    }
    
    struct POS{ //save pointers on Markers
      const char *APP;
      const char **DQT; //to save same pointers in 1 with index [DQTcount]
      const char *SOF;
      const char **DHT; //to save same pointers in 1 with index [DHTcount]
      const char *SOS;
      int  DQTcount; 
      int  DHTcount;
    };
    
    class Marker{
    public:
      Marker(); //Constructor
      ~Marker(); //Destructor
    .
    .
    .
    


  • Aha, also doch wieder der jpg-Decoder.

    Was alle schon gesagt haben, deine Zeiger sind uninitialisiert und Dereferenzierungen enden in undefiniertem Verhalten.

    Die Frage ist aber, warum du es so vorhast. Du kannst doch gleich die komplette Datei einlesen (vector bietet sich dafür an) und die Tags gleich auslesen. Wenn ich das richtig in Erinnerung habe, ist das jpg-Format in Chunks unterteilt. Der Header beginnt mit jeweils mit 0xFF gefolgt von der ID (SOI: 0xD8) und der Länge des Chunks (ohne die Länge selber, also minus 2 Byte).

    Du kannst also jeweils die Header einlesen und entsprechende Funktionen aufrufen. Wenn dich ein Chunk nicht interessiert, springst du einfach entsprechend weiter.

    Die Indizes würde ich nicht speichern - wozu auch?



  • Bitte den JPEG-Dekoder in einem Thread lassen. Es macht nichts, wenn er 200 Seiten groß wird.
    Dein Nächster Trhead dazu kann heißen "Ennos JPEG-Dekoder". Oder Du nennst diesen oder besser einen größeren alten dahin um. Alle anderen könnten gelöscht werden.



  • Ich stimme mappers Beitrag 100%ig zu. Dein aktueller Ansatz ist von grundauf eher Käse.



  • void Marker::findMarker(const char* SOI, size_t length){ 
       MPos.DQT = new const char*[2]; 
       MPos.DHT = new const char*[4]; 
       for(unsigned int i=0; i<length; i++){ 
         if(SOI[i] == (char)0xff){ 
           i++; 
           switch(SOI[i]){ 
             case (char)0xe0: 
               MPos.APP = &SOI[i]; 
               break; 
             case (char)0xdb: 
               MPos.DQT[MPos.DQTcount] = &SOI[i-1]; 
               MPos.DQTcount++; 
               break; 
             case (char)0xc0: 
               MPos.SOF = &SOI[i]; 
               break; 
             case (char)0xc4: 
               MPos.DHT[MPos.DHTcount] = &SOI[i]; 
               MPos.DHTcount++; 
               break; 
             case (char)0xda: 
               MPos.SOS = &SOI[i]; 
               break;     
           }//switch 
         }//if 
       }//for 
    }
    

    😮

    new und kein delete und wieso nicht gleich ein Vector? 😮



  • Bassmaster schrieb:

    void Marker::findMarker(const char* SOI, size_t length){ 
       MPos.DQT = new const char*[2]; 
       MPos.DHT = new const char*[4]; 
       for(unsigned int i=0; i<length; i++){ 
         if(SOI[i] == (char)0xff){ 
           i++; 
           switch(SOI[i]){ 
             case (char)0xe0: 
               MPos.APP = &SOI[i]; 
               break; 
             case (char)0xdb: 
               MPos.DQT[MPos.DQTcount] = &SOI[i-1]; 
               MPos.DQTcount++; 
               break; 
             case (char)0xc0: 
               MPos.SOF = &SOI[i]; 
               break; 
             case (char)0xc4: 
               MPos.DHT[MPos.DHTcount] = &SOI[i]; 
               MPos.DHTcount++; 
               break; 
             case (char)0xda: 
               MPos.SOS = &SOI[i]; 
               break;     
           }//switch 
         }//if 
       }//for 
    }
    

    😮

    new und kein delete und wieso nicht gleich ein Vector? 😮

    Hab es gepostet bevor ich damit fertig war. Delete ist drin 😉

    wie soll ich das bitte in einem vector lösen? Soll ich mir für jeden Pointer ein Vector machen?



  • Viel zu viel(e)
    - Sternchen
    - magische Konstanten ohne Namen
    - new[]

    Nochmal: Was spricht dagegen, das File in einem Rutsch zu lesen und gleichzeitig dabei die gefundenen Marker zu verarbeiten statt sich nur ihre Positionsn zu merken?


Anmelden zum Antworten