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!
-
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