Problem mit realloc



  • Hallo.

    Ich habe ein Problem mit der Funktion "realloc".

    Folgenden Code habe ich zusammengebastelt:

    Zunächst einmal die Definition meiner benutzerdefinierten Variablen TNode:

    typedef struct{
    	double x;
    	double y;
    
    	double Value[NV];
    
    	unsigned int nP;
    	unsigned long * EP;
    	double * Gamma;
    }TNode;
    

    Und hier der Code meiner Subfunction "CalcConnections". Erläuterung anschließend...

    int CalcConnections(unsigned long ***pElementsOnNode, unsigned long * MaxNodeConnectedElements, TQuad * fpQuad, TBar * fpBar, TNode * fpNode, unsigned long fnQuad, unsigned long fnBar, unsigned long fnNode){
    unsigned long fi=0, fj=0, fk=0, fl=0, fm=0;
    unsigned long fMaxNodeConnectedElements=0;
    unsigned long ** fpElementsOnNode, * fpConnections;
    unsigned long * pColumn = (unsigned long *)calloc(fnNode+1, sizeof(unsigned long));
    unsigned long * pnElementsOnNode = (unsigned long *)calloc(fnNode+1, sizeof(unsigned long));
    unsigned long * fpFluxConnectedElements = (unsigned long *)calloc(4, sizeof(unsigned long));
    unsigned int * fpnConnections;
    
    unsigned int fPrintElementConnections = 0;
    TQuad * fpQuadStart = fpQuad;
    TBar *  fpBarStart = fpBar;
    TNode * fpNodeStart = fpNode;
    
    SetnP(fpNode, fpQuad, fpBar, fnQuad, fnBar);
    fMaxNodeConnectedElements = GetMaxNodeConnectedElements(fpNode, fnNode);
    
    fpElementsOnNode = (unsigned long **)calloc(fnNode, sizeof(unsigned long *));
    do{
    	fpElementsOnNode[fi] = (unsigned long *)calloc(fMaxNodeConnectedElements, sizeof(unsigned long));
    }while(fi++<fnNode); fi=0;
    
    while(++fi<=fnQuad){
    	fpElementsOnNode[fpQuad->P1-1][pColumn[fpQuad->P1-1]++] = fi;
    	fpElementsOnNode[fpQuad->P2-1][pColumn[fpQuad->P2-1]++] = fi;
    	fpElementsOnNode[fpQuad->P3-1][pColumn[fpQuad->P3-1]++] = fi;
    	fpElementsOnNode[fpQuad->P4-1][pColumn[fpQuad->P4-1]++] = fi;
    	fpQuad++;
    }fi=0;fpQuad = fpQuadStart;
    
    while(++fi<=fnBar){
    	fpElementsOnNode[fpBar->P1-1][pColumn[fpBar->P1-1]++] = fi+fnQuad;
    	fpElementsOnNode[fpBar->P2-1][pColumn[fpBar->P2-1]++] = fi+fnQuad;
    	fpBar++;
    }fi=0;fpBar=fpBarStart;
    
    for (fi=0;fi<fnNode-1;fi++){
    	fpElementsOnNode[fi] = (unsigned long *)realloc(fpNode[fi].nP, sizeof(unsigned long));
    	fpNode[fi].EP = fpElementsOnNode[fi];
    }
    
    *pElementsOnNode = fpElementsOnNode;
    *MaxNodeConnectedElements = fMaxNodeConnectedElements;
    
    return 0;
    }
    

    In Zeile vier der Function wird eine Variable unsigned long ** fpElementsOnNode definiert.

    In den Zeilen 19 bis 22 mache ich daraus ein 2D Array.
    Dieses wird in Zeile 24 bis 36 befüllt. Zum Befüllen muss ich sagen,
    dass ich weiß, dass der erste Index soviele Einträge hat, wie die
    Variable "fnNode" angibt. Beim zweiten Index ist das unterschiedlich,
    jedoch werden es nie mehr Einträge als "fMaxNodeConnectedElements".

    Nach dem Befüllen weiß ich jedoch, wie groß der maximale zweite Index
    für jeden ersten Index ist. Deshalb versuche ich in Zeile 40 mit der
    Funktion realloc den nicht benutzten Speicher wieder freizugeben und
    anschließend der Pointer auf dieses 1D Array an meine Variable fpNode
    (Typ TNode) zu übergeben (die Übergabe macht keine Probleme). Bei
    realloc bekomme ich jedoch folgende Fehlermeldung:

    Beim TCC-Compiler: warning: assignment makes pointer from integer without a cast
    Beim LCC-Compiler: type error in argument 1 to `realloc'; found 'unsigned int' expected 'pointer to void'

    Mit beiden Warnungen / Fehlermeldungen kann ich nicht wirklich viel anfangen.
    Sieht jemand auf die Schnelle, woran das liegen kann?

    Ich weiß, man sollte bei C nicht probieren sondern nachdenken - aber ich habe die Zeile 40 auch mal so geschrieben:

    fpElementsOnNode[fi] = (unsigned long *)realloc(fpNode[fi-1]->nP, sizeof(unsigned long));
    

    Dann lautet die Fehlermeldung wie folgt:
    TCC-Compiler: pointer expected
    LCC-Compiler: left operand of -> has incompatible type 'TNode'

    P.s.: Ich habe den Code etwas gekürzt, sollte sich jemand denken, ich habe am Anfang nur aus Spaß so viele Variablen definiert 🙂 - der echte Code ist viel länger...



  • realloc erwartet als 1. Parameter einen Zeiger (auf ein mit xmalloc beschafften Speicherbereich). Du übergibst aber ein int.

    Schaun wir mal nach:

    typedef struct{
    ...
        unsigned int nP;
    ....
    }TNode;
    

    Ha, ist sogar eine unsigned. Der LCC hat mehr recht.



  • Danke Dirk, das wars.

    Das Problem war, dass ich calloc schon oft benutzt habe - realloc aber jetzt das erste Mal... und das erste Mal ist ja meistens scheiße 😉

    So funktioniert es:

    for (fi=0;fi<fnNode-1;fi++){
    	fpNode[fi].EP = (unsigned long *)realloc(fpElementsOnNode[fi], fpNode[fi].nP * sizeof(unsigned long));
    }
    

    Ja, ich habe beide Compiler. Der LCC wirft manchmal Fehler aus, die keine sind - ist aber kleinlicher und zeigt manchmal auch Fehler an, die welche sind, die der TCC aber ignoriert.



  • Verstehst du auch jetzt die Fehlermeldungen?
    Die waren eigentlich eindeutig. Gerade die vom LCC hat sogar noch den 1. Parameter genannt.



  • ...ist der Speicher, auf den der alte Pointer zeigt dann auch automatisch wieder frei gegeben?

    Ja, ich gebe zu: Die war mehr als eindeutig 💡



  • CJens schrieb:

    ...ist der Speicher, auf den der alte Pointer zeigt dann auch automatisch wieder frei gegeben?

    Ja.


Anmelden zum Antworten