Exceptionsicherer Code



  • Ich beschäftige mich derzeit mit OpenGL und implementiere dort einen Shader.
    Der Code zum Einlesen der Quelldatei ist folgender:

    vector<string> LineBuffer;
    	while (File) {
    		string Line;
    		getline(File, Line);
    		LineBuffer.push_back(Line);
    	}
    	if (File.bad())
    		throw runtime_error("Couldn't read shader");
    
    	size_t Size = LineBuffer.size();
    	const GLchar** CArray = new const GLchar*[Size];
    	for (int i = 0; i != Size; ++i)
    		CArray[i] = LineBuffer[i].c_str();
    
    	// Set shader source
    	glShaderSource(ShaderObject, Size, CArray, nullptr);
    
    	// Free char arrays
    	delete[] CArray;
    

    Ist irgendwie nicht sonderlich schön - funktioniert aber.
    Wie kann ich das eleganter und vor allem exceptionsicher machen?

    An glShaderSource muss ein Zeiger auf ein Array von Size null-terminierten C-Strings übergeben werden.

    Wenn im aktuellen Code nach Zeile 11 eine Exception fliegen würde, hätte man ein Speicherleck. Kann man das irgendwie verhindern?

    Gruß,
    Qwert



  • Qwert Zuiopü schrieb:

    Wenn im aktuellen Code nach Zeile 11 eine Exception fliegen würde, hätte man ein Speicherleck. Kann man das irgendwie verhindern?

    try/catch um den Code der werfen kann, und dann einfach die exception wieder werfen:

    vector<string> LineBuffer;
        while (File) {
            string Line;
            getline(File, Line);
            LineBuffer.push_back(Line);
        }
        if (File.bad())
            throw runtime_error("Couldn't read shader");
    
        size_t Size = LineBuffer.size();
        const GLchar** CArray = new const GLchar*[Size];
        try {
            for (int i = 0; i != Size; ++i)
                CArray[i] = LineBuffer[i].c_str();
    
            // Set shader source
            glShaderSource(ShaderObject, Size, CArray, nullptr);
    
            // Free char arrays
        } catch(...) {
            delete[] CArray;
            throw;
        }
        delete[] CArray;
    


  • Es kann so einfach sein.
    Danke!


  • Administrator

    Oder man verwendet Smart-Pointers, bzw. RAII.

    #include <boost/scoped_array.hpp>
    
    // ...
    
        vector<string> LineBuffer;
        while (File) {
            string Line;
            getline(File, Line);
            LineBuffer.push_back(Line);
        }
        if (File.bad())
            throw runtime_error("Couldn't read shader");
    
        size_t Size = LineBuffer.size();
        boost::scoped_array<const GLchar*> CArray(new const GLchar*[Size]);
    
        for (int i = 0; i != Size; ++i)
            CArray[i] = LineBuffer[i].c_str();
    
        // Set shader source
        glShaderSource(ShaderObject, Size, CArray, nullptr);
    

    Sowas sollte man wenn möglich immer einsetzen. Man kann dann auch nicht vergessen delete aufzurufen, da es automatisch passiert.

    Grüssli



  • Oder du nimmst Smart Pointer, damit sparst du dir den Extra try/catch Block.



  • Oder man nimmt einfach einen normalen vector 😉

    // ...
    
        vector<string> LineBuffer;
        while (File) {
            string Line;
            getline(File, Line);
            LineBuffer.push_back(Line);
        }
        if (File.bad())
            throw runtime_error("Couldn't read shader");
    
        size_t Size = LineBuffer.size();
        std::vector<GLchar const*> CArray(Size, 0);
    
        for (int i = 0; i != Size; ++i) {
            CArray[i] = LineBuffer[i].c_str();
        }
    
        // Set shader source
        glShaderSource(ShaderObject, Size, &CArray[0], nullptr);
    


  • xD

    Das geht natürlich auch. Wie hieß es noch gleich in dem Sprichwort mit dem Wald und den Bäumen?

    Danke für die Antworten.
    Gruß,
    Qwert


Log in to reply