Anzeige:
Ergebnis 1 bis 6 von 6

Thema: Speicherzugriffsfehler mit g++ 3.3.5

  1. #1
    Registrierter Benutzer
    Registriert seit
    29.07.2004
    Ort
    Berlin
    Beiträge
    40

    Speicherzugriffsfehler mit g++ 3.3.5

    Hi,

    das folgende Programm produziert einen Speicherzugriffsfehlr, fuer N>723.
    Code:
    //21.10.05 
    //
    using namespace std;
    
    #define N 724 //Matrix Groesse
    //N=724 giebt segemtaion fault, N=723 geht noch
    #define MAX_SHOWN_LINES 12
    
    #include <iostream>
    #include <cmath>
    
    int main(void){
    
     //bilden einer positiven symetrischen Matrix
     double aa[N*N];
     double aa_sym[N*N];
     //matrix zufaellig fuellen
     //
     double length=N*N;
     for(int i=0;i<length;i++){
       aa[i]=(double)i; 
     }
     //matrix symmetrisieren
    /* for(int i=0;i<N;i++){
       for(int j=0;j<N;j++){
         double sum=0;
         for(int k=0;k<N;k++){
           sum+= *(aa+i+k*N) * (*(aa+j+k*N)); 
           //cout<<"sum="<<sum<<endl;
         }
         *(aa_sym+j + N*i)=sum;
       } 
     } */
    
    }
    und zwar mit g++ 3.3.5. (hab das auf 3 verschiedenen Rechnern getestet). Komischerweise passiert das nicht mit g++ 3.3.4 (auf 2 Rechnern getestet).
    Kompiliert jeweils mit $g++ -g haupt_programm.cpp
    Der Speicherzugriffsfehler passiert auch nicht, wenn ich die zweite Array deklaration ausklammere oder die Groesse auf N beschraenke (double aa_sym[N*N]; ).
    gdb giebt mir folgendes:
    Code:
    Breakpoint 1, main () at haupt_programm.cpp:21
    21       double length=N*N;
    (gdb) n
    
    Program received signal SIGSEGV, Segmentation fault.
    0x080485cd in main () at haupt_programm.cpp:21
    21       double length=N*N;
    (gdb) n
    
    Program terminated with signal SIGSEGV, Segmentation fault.
    The program no longer exists.
    Was mich wundert, ist das der Fehler von der Groesse abhaengt. Und so besonders gross ist das ja nicht (~4MB), das sollte in 1GB Speicher reinpassen

    Sieht jemand den Fehler? Oder ist das ein Bug vom gcc?
    Ich hab das Programm mal angehaengt, zum ausprobieren. Die Kommentare sind teilweise nicht mehr ganz richtig, es ist ein Ausschnitt aus einem Programm zum loesen linearer Gleichungssysteme.

    Gruss,
    newton

  2. #2
    Registrierter Benutzer Avatar von Boron
    Registriert seit
    07.01.2002
    Beiträge
    827
    Wird da eventuell die maximale Stackgröße überschritten?

    Vielleicht solltest du deine Tabellen auf dem Heap anlegen:
    double* aa = new double[N*N];
    double* aa_sym = new double[N*N];

    Ach ja:
    Wenn schon C++, dann auf Makros verzichten (steht im Stroustrup so drin):
    const unsigned N 724;
    const unsigned MAX_SHOWN_LINES 12;
    Gruß Boron (der sich oft wegen mieser Rechtschreibung anderer die Augen reiben muss)

    LINUX IS LIKE AN INDIAN TENT: NO GATES, NO WINDOWS AND AN APACHE INSIDE!
    Hardware Monitoring unter Linux -> http://santafu.sourceforge.net (Temperaturen, Lüfterdrehzahlen und Spannungen)

  3. #3
    Registrierter Benutzer
    Registriert seit
    29.07.2004
    Ort
    Berlin
    Beiträge
    40
    Wird da eventuell die maximale Stackgröße überschritten?
    Hm, hatte ich auch schon ueberlegt, aber waere schon komisch, wenn das von gcc 3.3.4 zu 3.3.5 sich geaendert (verkleinert!) haette, oder? 1 Mio Array Elemente erscheint mir auch nicht so gross.
    Und vor allem, wenn ich nur _ein_ N*N array definiere, klappt das ja. Also kanns imho nicht die maximale Stackgroesse sein. Oder giebt es sowas wie maximalen Speicher pro programm?
    Vielleicht solltest du deine Tabellen auf dem Heap anlegen:
    double* aa = new double[N*N];
    double* aa_sym = new double[N*N];
    Das funktioniert, vielen Dank!
    Aber kannst Du mir den Unterschied erklaeren?
    Wenn schon C++, dann auf Makros verzichten (steht im Stroustrup so drin)
    Hat das technische Gruende, oder ist das mehr so eine Stilfrage?

    Gut, jetzt hab ich also einen Workaround, aber das eigentliche Problem noch nicht geloest. Wiso haengt das Auftauchen des Speicherzugriffsfehlers von der Array laenge bzw. der Anzahl der Arrays ab? Und wiso taucht das Problem bei ner anderen Compilerversion nicht auf? (waren uebrigen auch zwei verschiedene distries: gcc 3.3.4 auf ner suse 9.2, und gcc 3.3.5 auf debian 3.1)

    newton

  4. #4
    Registrierter Benutzer
    Registriert seit
    25.10.2004
    Beiträge
    819
    Zitat Zitat von newton
    1 Mio Array Elemente erscheint mir auch nicht so gross.
    1 Mio doubles, und das zweimal, macht 16MB Stack. Finde ich schon viel.

    Hat das technische Gruende, oder ist das mehr so eine Stilfrage?
    Mehr Stil. Bei defines kann der Compiler keine Überprüfung vornehmen, da er ja gar nichts sieht. consts sind schon besser und belegen ebenfalls keinen Speicherplatz. Außerdem kommt einem die Präprozessorersetzung nicht mehr in die Quere:
    Code:
    #define A 3+4
    const int B=3+4;
    int c = A*2; // = 11 (falsch! Man hätte #define A (3+4) schreiben müssen)
    int d = B*2; // = 14

  5. #5
    Registrierter Benutzer
    Registriert seit
    29.07.2004
    Ort
    Berlin
    Beiträge
    40
    Bei defines kann der Compiler keine Überprüfung vornehmen, da er ja gar nichts sieht.
    Ich dachte, zuerst kommt der preprocessor, der nimmt die ersetzungen der defines vor (und loescht die Kommentare), und giebt das dann weiter an den Compiler. Der Compiler wuerde dann ja durchaus sehen, was mittels define ersetzt wurde. Oder?

  6. #6
    Registrierter Benutzer
    Registriert seit
    25.10.2004
    Beiträge
    819
    Nö.

    Schreib mal ein kleines Programm mit ein paar Defines (und am besten ohne includes) und mache gcc -E datei.c. Das ist das, was der Compiler vom Präprozessor bekommt.

    Beispiel:
    Code:
    #define A 2+3
    main() { int x = A*4; }{
    bekommt der Compiler als
    Code:
    main() { int x = 2+3*4;}

Lesezeichen

Berechtigungen

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