RAII und new[]



  • Hallo,

    ich habe eine C-API vorliegen, die viele Funktionen der folgenden Art bereitstellt:

    int foo(some_handle* handles, size_t handle_count);
    

    Wenn ich nun eine solche Funktion aufrufen moechte, sieht mein Quellcode in etwa so aus:

    void bar(size_t count)
    {
      some_handle* handles = new some_handle[count];
    
      int rc = foo(handles, count);
    
      // wirft eventuell -> handles nicht freigegeben
      do_something_cpp(handles, count);
    
      if(rc < 0)
        throw some_error; // handles nicht freigegeben
    
      delete [] handles;
    }
    

    Jetzt moechte ich mir es ersparen innerhalb eines jeden if-Blocks den Speicher frei zu geben oder Funktionsaufrufe in einen try-catch-Block zu packen (zumal eine moegliche Ausnahme sowieso an den Aufrufer weitergegeben werden muesste).

    Ich weiss, dass das richtige Stichwort RAII lautet, aber nicht, welche Klasse man dafuer verwendet (abgesehen von einem selbsgebastelten Lock, ich gehe aber davon aus es existiert schon etwas). Bisher habe ich boost::scoped_array gefunden, passt das? Wie macht man es sonst?


  • Mod

    std::vector?



  • SeppJ schrieb:

    std::vector?

    Danke. Wie muss ich dann die C-Funktion korrekt aufrufen, so?

    std::vector<some_handle> handles;
    
    // vector fuellen ...
    
    foo((some_handle*)&handles, count);
    


  • henry_k schrieb:

    SeppJ schrieb:

    std::vector?

    Danke. Wie muss ich dann die C-Funktion korrekt aufrufen, so?

    std::vector<some_handle> handles;
    
    // vector fuellen ...
    
    foo((some_handle*)&handles, count);
    

    Ach du heilige Scheiße...

    foo(handles.data(), handles.size());
    


  • foo(handles.data(), handles.size());
    


  • Kellerautomat schrieb:

    foo(handles.data(), handles.size());
    

    Haha 😃



  • henry_k schrieb:

    foo((some_handle*)&handles, count);
    

    Autsch 🙄

    Unklarheit bestand vor allem darueber, ob man einen Zeiger uebergeben kann und die Elemente dann auch wie in einem Array angeordnet sind, aber das habe ich mittlerweile herausgefunden.

    Danke fuer die schnelle Hilfe!



  • So, wenn du nen aktuellen Compiler hast und den Rest von std::vector eh nicht brauchst:

    void bar(size_t count)
    {
      std::unique_ptr<some_handle[]> handles(new some_handle[count]);
    
      int rc = foo(handles, count);
      do_something_cpp(handles, count);
      if(rc < 0)
        throw some_error;
    }
    


  • Warum geht das nicht?

    void bar(size_t count)
    {
      some_handle handles[count];
    
      int rc = foo(handles, count);
    
      do_something_cpp(handles, count);
    
      if(rc < 0)
        throw some_error;
    }
    


  • NoNew schrieb:

    Warum geht das nicht?

    Weil das in C++ halt nicht erlaubt ist. VLA (Variable Length Arrays) gibts nur in C.


  • Mod

    NoNew schrieb:

    Warum geht das nicht?

    Weil count keine Compilezeitkonstante ist. VLAs (variable length arrays) gibt's nur in C. Und in manchen (sprich: einem) bekannten C++-Compilern als unportable Spracherweiterung. Außerdem schleppen VLAs noch einen ganzen Schwanz von Problemen mit sich, die sich mit dem strengeren Typsystem von C++ ganz besonders schlecht vertragen (das heißt aber nicht, dass es in C keine Probleme mit VLAs gäbe). Was ist zum Beispiel der Typ eines solchen Arrays?



  • *VORDIESTIRNKLATSCH*

    Stimmt natürlich. zuviel Java gemacht....



  • Java kann das erst recht nicht, da muss jedes Array mit new angelegt werden.



  • Ethon schrieb:

    So, wenn du nen aktuellen Compiler hast und den Rest von

    Fehlt da nicht irgendwie ein unique_ptr::get ?


Anmelden zum Antworten