Schreiben auf zweifelhafte Pointer



  • Hallo C++ Gemeinde, ich habe folgende Methode

    // vorwärtsdeklaration in der header datei
    bool getSomething(unsigned char *imgdata == NULL);
    
    // in der cpp datei
    bool getSomething(unsigned char *imgdata)
    {
    
    if(imgdata == NULL)
    {
      return false;
    }
    
    for(int i=0;i<size;i++)
    {
      imgdata[i] = ...
    }
    
    ...
    return true;
    }
    

    Ich erwarte in der Funktion einen Pointer einer bestimmten Größe und prüfe aber lediglich ob er auf NULL zeigt.

    Wie kann man sich davor absichern, dass ein nicht zu kleiner pointer übergeben wird?

    Wenn ich den Pointer innerhalb der Funktion initialisiere sieht man es außen nicht.

    // programmcode
    unsigned char *imgdata = NULL;
    bool test = getSomething(unsigned char imgdata);
    // nach dem Aufruf ist imgdata immer noch NULL ???
    
    // in der funktion
    bool getSomething(unsigned char *imgdata)
    {
    
    if(imgdata == NULL)
    {
      imgdata = new unsigned char[size];
    }
    
    for(int i=0;i<size;i++)
    {
      imgdata[i] = ...
    }
    
    ...
    return true;
    }
    

    Mir fällt jetzt als Anfänger nichts intelligentes ein. Ein sicherer Datentyp wie vector oder array ist leider nicht möglich weil die bildbibliothek die ich verwende leider einen unsigned char * erwartet.



  • Wieviel Speicher hinter einem Pointer für dich bereitsteht, kannst du leider nicht überprüfen. Die einfachste Lösung wäre es, wenn du dir vom Anwender mitteilen lässt, wieviel Platz dort tatsächlich zur Verfügung steht (und dann darauf vertraust, daß diese Angabe stimmt).

    Über die sysntaktischen Ungereimtheiten in deinem Code (Default-Parameter gibt man mit "=NULL" an und beim Aufruf einer Funktion nennt man nur die Parameternamen ohne Typ) erwähne ich jetzt nichts weiter.

    PS: Was hindert dich eigentlich daran, in deinem Code mit einem vernünftigen Container zu arbeiten und erst bei Übergabe an die externe Bibliothek die nackten Zeiger rauszugreifen?



  • Wo wird ein unsigned char* verwendet?
    Wenn's nur darum geht irgendwo irgendwas reinschreiben zu lassen, dann geht das mit std::vector wunderbar:

    std::vector<unsigned char> foo()
    {
        std::vector<unsigned char> buffer;
        size_t const size = some_lib_get_size();
        buffer.resize(size);
        some_lib_get_data(&buffer[0]);
        return buffer;
    }
    


  • So z.B.:

    typedef std::vector<unsigned char> image_buffer_type;
    
    //dann entweder
    bool get_something(image_buffer_type & buffer)
    {
        if(buffer.size() < size_to_read)
        {
            return false
        }
        else
        {
            for(std::size_t n = 0; n != buffer.size(); ++n)
            {
                buffer[n] = ...
            }
            return true;
        }
    }
    
    //...oder
    
    void get_something(image_buffer_type & buffer)
    {
        buffer.resize(size_to_read);
        for(std::size_t n = 0; n != buffer.size(); ++n)
        {
            buffer[n] = ...
        }    
    }
    


  • CStoll schrieb:

    Über die sysntaktischen Ungereimtheiten in deinem Code (Default-Parameter gibt man mit "=NULL" an und beim Aufruf einer Funktion nennt man nur die Parameternamen ohne Typ) erwähne ich jetzt nichts weiter.

    Stimmt. Danke für den Hinweis. Machte überhaupt keinen Sinn.

    hustbaer schrieb:

    Wo wird ein unsigned char* verwendet?

    In DevIL. Für OpenGL ist diese Bibliothek absolut klasse und sehr einfach zu erlernen. Bin für Alternativen natürlich offen.

    hustbaer schrieb:

    Wenn's nur darum geht irgendwo irgendwas reinschreiben zu lassen, dann geht das mit std::vector wunderbar:

    std::vector<unsigned char> foo()
    {
        std::vector<unsigned char> buffer;
        size_t const size = some_lib_get_size();
        buffer.resize(size);
        some_lib_get_data(&buffer[0]);
        return buffer;
    }
    

    Danke. Ich wusste gar nicht dass es gehen würde wenn die die Funktion einfach nur einen unsigned char * erwaret dass dort auch vector<unsigned char> rengeschoben werden kann. Werde gleich mal ausprobieren.

    Tachyon schrieb:

    So z.B.: ...

    Super! Danke auch!



  • pointerfrager schrieb:

    // programmcode
    unsigned char *imgdata = NULL;
    bool test = getSomething(unsigned char imgdata);
    // nach dem Aufruf ist imgdata immer noch NULL ???
    
    bool getSomething(unsigned char *imgdata)
    {
    ...
    }
    

    Ja, da du nur der lokalen Kopie des Zeigers einen neuen Wert zuweist.
    Soll sich der Effekt nach aussen bemerkbar machen, dann musst du den Zeiger als Referenz übergeben (wie bei anderen Datentypen auch).



  • Jockelx schrieb:

    Ja, da du nur der lokalen Kopie des Zeigers einen neuen Wert zuweist.
    Soll sich der Effekt nach aussen bemerkbar machen, dann musst du den Zeiger als Referenz übergeben (wie bei anderen Datentypen auch).

    Das ich selbst nicht drauf gekommen bin... 🙄 Dankeschön



  • Jockelx schrieb:

    Soll sich der Effekt nach aussen bemerkbar machen, dann musst du den Zeiger als Referenz übergeben (wie bei anderen Datentypen auch).

    Dabei solltest du übrigens darauf achten, daß der Aufrufer weiß wie er den zurückgegebenen Speicherbereich wieder freigeben kann. (außerdem hilft die Konstruktion nicht, wenn der Anwender weniger Speicher angefordert hat als du benötigst)


Anmelden zum Antworten