- LiFePO4 Speicher Test         
Ergebnis 1 bis 7 von 7

Thema: realloc zweidimensionals Array

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2009
    Ort
    NRW
    Beiträge
    23

    realloc zweidimensionals Array

    Anzeige

    Powerstation Test
    Hi zusammen,

    ich hoffe, meine Frage ist hier richtig. Es geht um ein generelles Problem in C, nicht in Bezug auf spezielle Hardware/µC.
    Ich versuche mich gerade an der dynamischen Speicherverwaltung mit zweidimensionalen Arrays. Durch googlen hab ich das mit malloc super hingekriegt. Jetzt will ich das Array aber auch vergrößern und verkleinern, also mit realloc arbeiten. Dazu hab ich leider nichts gefunden, dass mir wirklich weiterhelfen würde.
    Mein Code sieht aktuell so aus:

    Code:
    void main(void){
        int i, j;
        double **testarray = NULL;
        
        testarray = (double**) realloc(testarray, 5 * sizeof(double*));
        
        for (i = 0; i < 5; i++){
            if(testarray[i] = (double*) realloc(testarray, 5 * sizeof(double)) == NULL)
                printf("\nFEHLER\n");
            else
                printf("\nOK\n");
        }
        
        
        // Werte in gerade vergrößertes Array schreiben
        for(i=0; i<5; i++){
            for(j=0; j<5; j++){
                testarray[i][j] = i+j;
            }
        }
        
        // Ausgabe
        for(i=0; i<5; i++){
            for(j=0; j<5; j++){
                printf("testarray[%i][%i] = %f\n", i, j, testarray[i][j]);
            }
        }
    
    }
    Ich bekomme auch fünfmal "OK" angezeigt, aber wenn dann Werte in das Array geschrieben werden sollen, stürzt das Programm ab.
    Was mache ich falsch?

    Danke schonmal für jeden Tip!

    Schönen Sonntag,
    V:X

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    1) Du hast da gar kein zweidimensionales Array. Du hast mehrere eindimensionale Arrays und ein zusätzliches Array mit Zeigern auf die Arrays. Der Zugriff sieht zwar genauso aus, aber das Layout im Speicher ist gänzlich anders. Und dementsprechend sähe ein Vergrößern eines "echten" zweidimensionalen Arrays auch ganz anders aus.

    2)
    Code:
    if(testarray[i] = (double*) realloc(testarray, 5 * sizeof(double)) == NULL)
    Hier müsste es eigentlich "realloc(testarray[i]," heißen.

    3) Punkt 2 löst dein Problem aber nicht vollständig. Du darfst als ersten Parameter an realloc nur einen Pointer übergeben, den eine der *alloc-Funktionen geliefert hat, oder Null. Du übergibst in der Schleife aber uninitialisierten Müll an realloc. Nach dem realloc des Pointer-Arrays musst du die neuen Pointer erst mal Nullen.
    MfG
    Stefan

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2009
    Ort
    NRW
    Beiträge
    23
    Danke für die schnelle Antwort!

    Aber leider stürzt mein Programm immer noch ab. Ich hab den Schleifeninhalt jetzt so geändert, dass ein mit NULL initialisierter Pointer übergeben wird:

    Code:
    for (i = 0; i < 5; i++){
            testarray[i] = NULL;
            if( testarray[i] = (double*) realloc(testarray[i], 5 * sizeof(double)) == NULL)
                printf("\nFEHLER\n");
            else
                printf("\nOK\n");
        }
    Ich erhalte auch immer die folgende Warnung:

    Code:
    warning: assignment makes pointer from integer without a cast
    Damit kann ich nicht viel anfangen. Ich erstelle doch gar keinen int-Poiter?

    Ich würd mich freuen, wenn ihr mir nochmal auf die Sprünge helfen könntet!

    Danke schonmal und schönen Abend noch,
    V:X

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von V:X Beitrag anzeigen
    Ich erhalte auch immer die folgende Warnung:

    Code:
    warning: assignment makes pointer from integer without a cast
    Damit kann ich nicht viel anfangen. Ich erstelle doch gar keinen int-Poiter?
    Das behauptet die Warnung ja auch gar nicht. Sie behauptet, dass du mittels einer Zuweisung aus einem Integer direkt (ohne expliziten Cast) einen Pointer machst. Und sie hat Recht. In dieser Zeile
    Code:
    if( testarray[i] = (double*) realloc(testarray[i], 5 * sizeof(double)) == NULL)
    fehlt eine Klammerung.


    PS: Und noch was Grundsätzliches: warum steht in deinem ersten Post nichts von der Warnung?
    Warnungen ignoriert man nicht einfach, erst recht nicht, wenn man sie nicht versteht. Und wenn du in einem Forum wegen einem Code-Problem nachfragst, dann schreibe auch dazu, was der Compiler zu dem Code zu sagen hat. Für andere können die Warnungen schließlich wertvolle Hinweise enthalten.
    Geändert von sternst (03.07.2011 um 22:17 Uhr)
    MfG
    Stefan

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2009
    Ort
    NRW
    Beiträge
    23
    Schau an, die fehlende Klammerung war die Lösung! Danke für den Hinweis!

    Hast ja Recht, wegen der Warnung. Aber das ist jetzt echt der erste Fall, wo mir eine Warnung wirklich an einer "funktionskritischen" Stelle erscheint. Bisher hab ich nur Warnungen erlebt mit einer Wichtigkeit von "Variable XY ist angelegt, wird aber nie verwendet". Sprich, die erschienen mir bisher einfach wenig wichtig. Aber da bin ich wohl nicht der erste

    Aber so 100%ig hab ich das jetzt noch nicht verstanden. Ich würde jetzt meinen, dass durch
    Code:
    if( testarray[i] = (double*) realloc(testarray[i], 5 * sizeof(double)) == NULL)
    keine klare Trennung zwischen Zuweisung und Vergleich gegeben ist. Und dann kommt es bei der Programmausführung zu einem (Speicher?-) Fehler, was durch die zusätzliche Klammerung wiederum verhindert wird.

    Und du hast geschrieben, dass ich
    mittels einer Zuweisung aus einem Integer direkt (ohne expliziten Cast) einen Pointer
    mache. Aber oben habe ich doch
    Code:
    double **testarray
    deklariert. Dann ist es doch ein double-Zeiger auf einen Speicherbereich, in dem ich weitere double-Zeiger habe. Die ich erweitern und daher wie ein Array verwenden kann. Oder nicht?
    Mir ist noch nicht klar, wo bei der Sache "auf einmal" das Integer herkommt.

    Danke schonmal für jeden Denkanstoß!
    V:X

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von V:X Beitrag anzeigen
    Ich würde jetzt meinen, dass durch
    Code:
    if( testarray[i] = (double*) realloc(testarray[i], 5 * sizeof(double)) == NULL)
    keine klare Trennung zwischen Zuweisung und Vergleich gegeben ist.
    Warum? Was genau soll denn diese "klare Trennung" sein?

    Zwei Dinge sind dir hier offenbar noch nicht klar:
    1)
    ==, != , <, >, das sind alles ganz normale Operatoren, wie +, -, *, etc. Es gibt da keinen Unterschied.
    2)
    Es gibt auch keinen besonderen Zusammenhang zwischen dem if und diesen Operatoren. Dem if ist es völlig egal, was genau da in der Klammer steht. Zuerst wird der Ausdruck in der Klammer komplett ausgerechnet, und für das if ist dann nur das Endergebnis dieser Berechnung von Interesse. Nämlich ob es 0 oder nicht 0 ist.

    Bei deiner Zeile stehen also einfach nur drei Operanden mit zwei Operatoren dazwischen:
    Code:
    A = B == C
    Da es keine Klammern gibt, regelt die Operator-Precedence in welcher Reihenfolge das ausgewertet wird. Und da der ==-Operator eine höhere Präzedenz hat (man kann auch sagen: bindet stärker) wird zuerst der Vergleich B == C ausgewertet. Das Ergebnis davon wird dann an A zugewiesen. Und das Ergebnis der Zuweisung ist dann das, was das if auswertet. Das Ergebnis des ==-Operators ist übrigens ein Integer, der entweder 0 (nicht gleich) oder 1 (gleich) ist. Und daher auch die Warnung: dem Pointer A wird ein Integer (Ergebnis von B == C) zugewiesen.
    Geändert von sternst (05.07.2011 um 00:08 Uhr)
    MfG
    Stefan

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    27.08.2009
    Ort
    NRW
    Beiträge
    23
    Da es keine Klammern gibt, regelt die Operator-Precedence in welcher Reihenfolge das ausgewertet wird. Und da der ==-Operator eine höhere Präzedenz hat (man kann auch sagen: bindet stärker) wird zuerst der Vergleich B == C ausgewertet. Das Ergebnis davon wird dann an A zugewiesen. Und das Ergebnis der Zuweisung ist dann das, was das if auswertet. Das Ergebnis des ==-Operators ist übrigens ein Integer, der entweder 0 (nicht gleich) oder 1 (gleich) ist. Und daher auch die Warnung: dem Pointer A wird ein Integer (Ergebnis von B == C) zugewiesen.
    Jetzt ist der Groschen gefallen!!
    Vielen Dank für die Hilfe und abschließende Erklärung!

    Grüße,
    V:X

Ähnliche Themen

  1. LED Array
    Von filth im Forum Elektronik
    Antworten: 7
    Letzter Beitrag: 09.12.2008, 12:06
  2. Array
    Von infection im Forum C - Programmierung (GCC u.a.)
    Antworten: 4
    Letzter Beitrag: 26.05.2008, 21:47
  3. Array auf zweidimensionale Array
    Von semicolon im Forum C - Programmierung (GCC u.a.)
    Antworten: 1
    Letzter Beitrag: 25.05.2007, 12:48
  4. Nur Nummern in Array / nur Variablentyp byte als Array?
    Von Crashmichl im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 27.04.2006, 23:15
  5. ATmega16 und Array
    Von slope im Forum AVR Hardwarethemen
    Antworten: 4
    Letzter Beitrag: 05.02.2005, 20:47

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test