Aufruf einer Funktion führt zu Speicherzugriffsfehler



  • Hallo,

    ich hab ein Problem bei dem Aufruf einer Funktion und weiß echt nicht mehr weiter. Bin der Meinung schon echt alles ausprobiert zu haben.

    Das ganze Programm ist sehr umfangreich und deshalb hier ein Auschnitt:
    Aufruf der Funktion:

    cout << "\n before UltraLocalProjection3D \n"  << endl;
          if(TDatabase::ParamDB->LP_FULL_GRADIENT)
            UltraLocalProjection3D(MatricesA[k], FALSE, BilinearCoeffs);
          cout << "\n after UltraLocalProjection3D \n"  << endl;
    

    Ausschnitt aus der Funktion UltraLocalProjection3D:

    void UltraLocalProjection3D(void* A, boolean ForPressure, CoeffFct3D *Coeff)
          {	  
    	      cerr << "\n start of UltraLocalProjection3D \n"  << endl;
    		  int i,j,k,l,m,n;
    

    Als Ausgabe bekomme ich immer:

    before UltraLocalProjection3D
    
     Segmentation fault
    

    MatricesA[k] sollte eigentlich ein Feld von Zeigern sein. Aber egal ob ich statt MatricesA[k] etwas anderes wie NULL, 0, ein Array von irgendeinem Datentyp einsetzte, es kommt immer wieder der gleich Fehler.

    Ich habe gdb und valgrind drüber laufen lassen:

    valgrind:

    before UltraLocalProjection3D
    
    ==4708== Warning: client switching stacks?  SP change: 0x7FEFFF0E0 --> 0x7F87AA520
    ==4708==          to suppress, use: --max-stackframe=109398976 or greater
    ==4708==
    ==4708== Invalid write of size 8
    ==4708==    at 0x522DC8: UltraLocalProjection3D(void*, boolean, void (*)(int, double*, double*, double*, double**, double**)) (LocalProjection3D.C:283)
    ==4708==  Address 0x7F87AA598 is on thread 1's stack
    ==4708==
    ==4708== Process terminating with default action of signal 11 (SIGSEGV)
    ==4708==  Access not within mapped region at address 0x7F87AA598
    ==4708==    at 0x522DC8: UltraLocalProjection3D(void*, boolean, void (*)(int, double*, double*, double*, double**, double**)) (LocalProjection3D.C:283)
    ==4708==
    ==4708== Invalid write of size 8
    ==4708==    at 0x6A5B348: _vgnU_freeres (in /usr/lib64/valgrind/amd64-linux/vgpreload_core.so)
    ==4708==  Address 0x7F87AA518 is on thread 1's stack
    ==4708==
    ==4708== Process terminating with default action of signal 11 (SIGSEGV)
    ==4708==  Access not within mapped region at address 0x7F87AA518
    ==4708==    at 0x6A5B348: _vgnU_freeres (in /usr/lib64/valgrind/amd64-linux/vgpreload_core.so)
    

    gdb

    before UltraLocalProjection3D
    
    Program received signal SIGSEGV, Segmentation fault.
    0x0000000000522df0 in UltraLocalProjection3D (A=Cannot access memory at address 0x7fff4440b1d8
    ) at ../LocalProjection3D.C:283
    283     void UltraLocalProjection3D(void* A, boolean ForPressure, CoeffFct3D *Coeff)
    (gdb) info stack
    #0  0x0000000000522df0 in UltraLocalProjection3D (A=Cannot access memory at address 0x7fff4440b1d8
    ) at ../LocalProjection3D.C:283
    #1  0x0000000000404eb4 in main (argc=2, argv=0x7fff4ac60978) at Tutorial/CD_3D_LPS.C:615
    (gdb)
    

    Warum hat er mit dem Aufruf der Funktion UltraLocalProjection3D solche Probleme? Wie kann es dazu kommen das er beim Aufruf der Funktion ein Speicherzugriffsfehler erzeugt?

    Danke.



  • Wenn Du das ganze Feld der Funktion übergibst, dann geschieht das über den Stack. Ist das Feld zu groß, so kommt es zum Stacküberlauf.

    Kann es sein, das Du nicht "void *A" sondern evtl. void **A wolltest? 😉

    Gruß
    Trooper



  • Nein, das ist schon ok so. Hab mich wohl falsch ausgedrückt.

    Aber die Zuweisung geschieht ungefähr folgender maßen:
    TSquareMatrix3D *sqmatrixA;
    [...]
    MatricesA[k] = sqmatrixA;



  • poohbaer schrieb:

    Nein, das ist schon ok so. Hab mich wohl falsch ausgedrückt.

    Aber die Zuweisung geschieht ungefähr folgender maßen:
    TSquareMatrix3D *sqmatrixA;
    [...]
    MatricesA[k] = sqmatrixA;

    das [...] ist wichtig ... falls da nicht noch irgendwo sqmatrixA = new irgendwas[]; oder sqmatrixA = &neInitialisierteTSuareMatrix3D (oder so ähnlich) kommt, hast du einen Zeiger der irgendwo hin zeigt und nicht dahin wo du schreiben darfst ...

    mach mal TSquareMatrix3D *sqmatrixA = 0; und dann in der Zeile bevors kracht if (! sqmatrixA) std::cout << "sqmatrixA zeigt sonst wo hin" << std::endl;



  • padreigh schrieb:

    mach mal TSquareMatrix3D *sqmatrixA = 0; und dann in der Zeile bevors kracht if (! sqmatrixA) std::cout << "sqmatrixA zeigt sonst wo hin" << std::endl;

    Das "funktioniert". Aber sqmatrixA zeigt nur sonst wo hin wenn ich es vorher wie beschrieben 0 setze. Sonst scheint alles in Ordnung zu sein.

    Hier mal im Wesentlichen die Zuweisung der von MatricesA[k]:

    [...]
      TSquareStructure3D *sqstructureA;
      TSquareMatrix3D *sqmatrixA;
      TSquareMatrix3D **MatricesA;
      TFESpace3D *velocity_space;
      MatricesA = new TSquareMatrix3D*[LEVELS+1];
    [...]
    for(i=0;i<LEVELS;i++)
    { 
      mg_level++;
      [...]  
      for(k=k0;k<=mg_level;k++)
      {
    	[...]
        if ((mg_type==1)&&(k<mg_level))
          velocity_space =  new TFESpace3D(coll, Name, UString, BoundCondition, -1);
        else
          velocity_space =  new TFESpace3D(coll, Name, Description, BoundCondition, ORDER);
        // build matrices 
        sqstructureA = new TSquareStructure3D(velocity_space);
        sqstructureA->Sort();
        // allocate matrices
        sqmatrixA = new TSquareMatrix3D(sqstructureA);
        MatricesA[k] = sqmatrixA;
        [...]
      }
      [...]
    }
    [...]
    

    Danke.



  • Hmmm, ich habe jetzt noch mal etwas getestet und bin nun ganz verwirrt. 😕

    Ich habe die Funktion UltraLocalProjection3D so bearbeitet, dass sie unabhängig ist. Also nur noch

    UltraLocalProjection3D();
    

    aufgerufen wird. Trotzdem wird mir ein Speicherzugriffsfehler ausgegeben.

    Es ist doch richtig das er mit Hilfe von cerr eine Text-Ausgabe ungepuffert ausgibt,oder?

    EDIT: Vielen Dank für die Ideen und Ansätze. Hab das Problem gelöst. In der Funktion UltraLocalProjection3D habe ich ein Array initialisiert, was anscheinend nicht zulässig war. Ich lebte in den Irrglauben das cerr mir eine Textausgabe ungepuffert ausgibt bevor er irgendwelche Variablen initielisiert.


Anmelden zum Antworten