Dynamische Speicherverwaltung



  • Hallo Leute,

    habe ein kleines Problem mit der dynamischen Verwaltung von Speicherbereichen und hoffe mich kann einer von euch aufklären was ich falsch mache.
    Hier erstmal mein Code:

    typedef unsigned int uint;
    
    uint **triangle;
    
    for (uint i = 0; i < 15; ++i) {
    	cout << "Allocating " << (i + 1) * sizeof(uint *) << " Bytes of memory for uint-pointers" << endl;
    	triangle = (uint **)realloc(triangle, (i + 1) * sizeof(uint *));
    
    	if (triangle != NULL) {
    		cout << "Allocating " << (i + 1) * sizeof(uint) << " Bytes of memory for uint values" << endl;
    		triangle[i] = (uint *)malloc((i + 1) * sizeof(uint));
    
    		if (triangle[i] != NULL) {
    			cout << "Filling uint values" << endl;
    			for (uint j = 0; j <= i; ++j) {
    				triangle[i][j] = 12321;
    
    				cout << triangle[i][j] << endl;
    			}
    		}
    	}
    }
    

    Ich versuche ein Dreieck aus uint-Werten zu erstellen, was in etwa so aussieht:

    uint dreieck[zeilen][spalten] = {
    	{77},
    	{55, 66},
    	{44, 33, 22}
    };
    

    Leider beendet sich die Anwendung mit einem Laufzeitfehler, sobald ich Speicher für die Spalte reservieren will, also bei:

    triangle[i] = (uint *)malloc((i + 1) * sizeof(uint));
    

    Kann mir bitte jemand sagen, wie das richtig geht?



  • cpprogrammer schrieb:

    Kann mir bitte jemand sagen, wie das richtig geht?

    Mit vector .



  • Natürlich mit vector 🕶

    Aber nehmen wir mal an, ich hätte keinen vector zur Verfügung und müsste das selbst machen.
    Laut C Openbook müsste es doch so funktionieren, wie ich es gemacht habe 😕



  • C von A bis Z ist so ziemlich eins der schlechtesten, fehlerhaftesten Bücher, die existieren.



  • triangel ist nicht initialisert, und damit rufst du realloc auf. Das kann der Grund sein, weiter habe ich nicht geguckt. Benutz´ den Debugger und geh´ das Programm Schritt für Schritt durch, bis es knallt. Ich weiß nicht, auf welchem OS und mit welcher Compiler du arbeitest, aber oft gibt es Tools, die ungültige Speicherzugriffe prüfen. Sowas solltest du ebenfalls einsetzen, wenn es sowas für dein OS/Compiler gibt.



  • cpprogrammer schrieb:

    Aber nehmen wir mal an, ich hätte keinen vector zur Verfügung

    Dann würdest du einen schreiben.



  • @DocShoe:
    Ja, triangle ist nicht initialisiert. Das ist richtig.
    Aber in der Referenz von cpluscplus.com steht:

    In case that ptr is NULL, the function behaves exactly as malloc, assigning a new block of size bytes and returning a pointer to the beginning of it.

    Deshalb geh ich davon aus, dass triangle im ersten Schleifendurchlauf einen uint-Zeiger aufnehmen kann, den ich unten mit malloc hole. Im nächsten dann wieder einen mehr usw.

    @TyRoXx:
    Ich wusste, dass die Antwort kommt ^^
    Du hast im Normalfall natürlich recht, aber ich würde halt gern wissen, wie ich es auf diesem Weg hinbekomme. Wenn ich zum Beispiel in C programmieren würde, dann hätte ich diesen vector eben nicht und könnte ihn mir, soweit ich weiß, auch nicht schreiben (ob das mit structs geht weiß ich nicht, mit denen hab ich mich nie so sehr beschäftigt).



  • cpprogrammer schrieb:

    @DocShoe:
    Ja, triangle ist nicht initialisiert. Das ist richtig.
    Aber in der Referenz von cpluscplus.com steht:

    In case that ptr is NULL, the function behaves exactly as malloc, assigning a new block of size bytes and returning a pointer to the beginning of it.

    Ich zitier mal aus einem Tutorial, das ich im weltweiten INet gefunden habe:
    "Es ist keineswegs gesichert, dass eine neu angelegte Variable den Wert 0 hat, solange Sie das nicht explizit festlegen."



  • cpprogrammer schrieb:

    Ja, triangle ist nicht initialisiert. [...]

    In case that ptr is NULL, [...].

    "Nicht initialisiert" und "is NULL" sind zwei völlig verschiedene Paar Schuhe.
    "Nicht initialisiert" heißt bei PODs "Enthält irgendeinen Speichermist", in dem Fall also "enthält irgendeine Adresse aber mit ziemlicher Sicherheit nicht NULL".



  • Oh man, bin ich dämlich... Natürlich habt ihr alle Recht. Das hab ich total übersehen 🙄
    Solange ich triangle nicht mit NULL (oder etwas anderem) initialisiere kann dort alles mögliche stehen, was realloc dann wieder zum erweitern des Speicherbereiches verwenden möchte.

    Vielen Dank für eure Hilfe 👍


Anmelden zum Antworten