Speicherzugriffsfehler - Werde aus Compilerfehlermeldung nicht schlau



  • Hallo,

    ich hab ein längeres Programm für eine numerische Berechnung geschrieben (Heisenberg-Spinkette).
    Für kleine Ketten funktioniert das Programm, d.h. ich erhalte die richtigen Resultate und es spuckt keine Fehlermeldung aus. Für größere Ketten passiert jedoch das:

    *** glibc detected *** ./getmatrix.o: munmap_chunk(): invalid pointer: 0x09612a50 ***
    ======= Backtrace: =========
    /lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x3da591]
    /lib/tls/i686/cmov/libc.so.6(+0x6c80e)[0x3db80e]
    /usr/lib/libgsl.so.0(gsl_matrix_complex_free+0x2d)[0x1b6fad]
    ./getmatrix.o[0x804a632]
    /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0x385bd6]
    ./getmatrix.o[0x8049171]
    ======= Memory map: ========
    00110000-002e8000 r-xp 00000000 08:15 151341     /usr/lib/libgsl.so.0.14.0
    002e8000-002ea000 r--p 001d7000 08:15 151341     /usr/lib/libgsl.so.0.14.0
    002ea000-002f2000 rw-p 001d9000 08:15 151341     /usr/lib/libgsl.so.0.14.0
    002f2000-0036d000 r-xp 00000000 08:15 179659     /usr/lib/libblas.so.3gf.0
    0036d000-0036e000 r--p 0007a000 08:15 179659     /usr/lib/libblas.so.3gf.0
    0036e000-0036f000 rw-p 0007b000 08:15 179659     /usr/lib/libblas.so.3gf.0
    0036f000-004c2000 r-xp 00000000 08:15 142905     /lib/tls/i686/cmov/libc-2.11.1.so
    004c2000-004c3000 ---p 00153000 08:15 142905     /lib/tls/i686/cmov/libc-2.11.1.so
    004c3000-004c5000 r--p 00153000 08:15 142905     /lib/tls/i686/cmov/libc-2.11.1.so
    004c5000-004c6000 rw-p 00155000 08:15 142905     /lib/tls/i686/cmov/libc-2.11.1.so
    004c6000-004c9000 rw-p 00000000 00:00 0 
    004dd000-004fa000 r-xp 00000000 08:15 717        /lib/libgcc_s.so.1
    004fa000-004fb000 r--p 0001c000 08:15 717        /lib/libgcc_s.so.1
    004fb000-004fc000 rw-p 0001d000 08:15 717        /lib/libgcc_s.so.1
    006a4000-006a5000 r-xp 00000000 00:00 0          [vdso]
    00bbd000-00ca6000 r-xp 00000000 08:15 145230     /usr/lib/libstdc++.so.6.0.13
    00ca6000-00ca7000 ---p 000e9000 08:15 145230     /usr/lib/libstdc++.so.6.0.13
    00ca7000-00cab000 r--p 000e9000 08:15 145230     /usr/lib/libstdc++.so.6.0.13
    00cab000-00cac000 rw-p 000ed000 08:15 145230     /usr/lib/libstdc++.so.6.0.13
    00cac000-00cb3000 rw-p 00000000 00:00 0 
    00de8000-00e0c000 r-xp 00000000 08:15 152198     /lib/tls/i686/cmov/libm-2.11.1.so
    00e0c000-00e0d000 r--p 00023000 08:15 152198     /lib/tls/i686/cmov/libm-2.11.1.so
    00e0d000-00e0e000 rw-p 00024000 08:15 152198     /lib/tls/i686/cmov/libm-2.11.1.so
    00e43000-00f07000 r-xp 00000000 08:15 132031     /usr/lib/libgfortran.so.3.0.0
    00f07000-00f08000 ---p 000c4000 08:15 132031     /usr/lib/libgfortran.so.3.0.0
    00f08000-00f09000 r--p 000c4000 08:15 132031     /usr/lib/libgfortran.so.3.0.0
    00f09000-00f0a000 rw-p 000c5000 08:15 132031     /usr/lib/libgfortran.so.3.0.0
    00f0a000-00f0b000 rw-p 00000000 00:00 0 
    00fd5000-00ff0000 r-xp 00000000 08:15 1306       /lib/ld-2.11.1.so
    00ff0000-00ff1000 r--p 0001a000 08:15 1306       /lib/ld-2.11.1.so
    00ff1000-00ff2000 rw-p 0001b000 08:15 1306       /lib/ld-2.11.1.so
    08048000-08051000 r-xp 00000000 08:21 189        /media/M-S325/heisenbergV2.0/src/getmatrix.o
    08051000-08052000 r--p 00008000 08:21 189        /media/M-S325/heisenbergV2.0/src/getmatrix.o
    08052000-08053000 rw-p 00009000 08:21 189        /media/M-S325/heisenbergV2.0/src/getmatrix.o
    09612000-09633000 rw-p 00000000 00:00 0          [heap]
    b7707000-b770a000 rw-p 00000000 00:00 0 
    b7720000-b7723000 rw-p 00000000 00:00 0 
    bfae7000-bfafc000 rw-p 00000000 00:00 0          [stack]
    Aborted
    

    Der Fehler tritt dabei auf, wenn im Code folgender Befehl ausgeführt wird:

    gsl_matrix_complex_free(Hamiltonian);
    

    Die Funktion gsl_Matrix_complex_free ist Teil der Gnu Scientific Library, sie gibt den Speicher der Matrix "Hamiltonian" wieder frei.
    Ich weiß (da ich die Matrix eine Zeile vorher noch ausgegeben habe), dass die Matrix existiert und auch Einträge hat.
    Hat jemand von euch eine Idee, was genau falsch läuft?
    Da der Code recht lang ist, habe ich ihn nicht angehangen, kann ich aber bei Bedarf gerne noch machen.
    Vielen Dank schonmal!



  • kaesekuchen86 schrieb:

    Hat jemand von euch eine Idee, was genau falsch läuft?

    Nicht ohne Glaskugel bei diesem Bisschen an Infos. Laut Fehlermeldung ist ein Zeiger ungültig, also würde ich mal prüfen, was du gsl_matrix_complex_free da übergibst. Vielleicht mehrfache Freigabe?



  • Sorry für die wenigen Infos, ich bin noch nicht so fit im Programmieren und weiß leider noch nicht, was genau für das Problem relevant ist.

    Also hier ist mal der Output des Programms kurz vor dem Absturz:

    Gsl Matrix:
    0	0	0.5	0
    0	1	0.5	0
    0	2	0.5	0
    0	3	0	0
    1	0	-0.707107	0
    1	1	0.5	0
    1	2	1	0
    1	3	0.866025	0
    2	0	0.414214	0
    2	1	-1.22474	0
    2	2	-1.5	0
    2	3	0.866025	0
    3	0	0	0
    3	1	-1	0
    3	2	1.9559e-16	0
    3	3	-1.5	0
    Delete Hamiltonian matrix...
    *** glibc detected *** ./getmatrix.o: munmap_chunk(): invalid pointer: 0x09612a50 ***
    

    Man sieht also, dass die Matrix wirklich existiert (erste Spalte: erster Index, zweite Spalte: zweiter Index, dritte Spalte: Realteil des Eintrags, vierte Spalte: Imaginärteil des Eintrags).

    Code einfügen scheint irgendwie nicht zu funktionieren, ich hab keine Ahnung wieso, ich lad ihn einfach mal hier hoch:
    http://rapidshare.com/files/396245226/getmatrix.cpp.html



  • kaesekuchen86 schrieb:

    Code einfügen scheint irgendwie nicht zu funktionieren, ich hab keine Ahnung wieso, ich lad ihn einfach mal hier hoch:
    http://rapidshare.com/files/396245226/getmatrix.cpp.html

    Der Code ist wohl zu lang.
    Das nächste mal aber besser pastebin verwenden.

    Ich hatte keine Probleme. Läuft komplett durch.
    Welche Version von gsl hast du denn installiert? Hier 1.13. Welchen GCC verwendest du?



  • Also gsl hab ich Version "1.13+dfsg-1" und gcc Version 4:4.4.3-1ubuntu1 laut Synaptic Paket Manager. Betriebssystem ist ubuntu.

    EDIT: Bin mir nicht sicher, ob die Angabe zu gcc absolut richtig ist. Das Paket "gcc" hat oben angegebene Version, das Paket "gcc-4.4-base" hat Version "4.4.3-4ubuntu5" laut Synaptic.



  • Wie wärs wenn du einen Testcase schreibst und ihn hier präsentierst?



  • Sorry, was genau ist ein Testcase?



  • Reduzier deinen Code auf das absolut nötigste um den Fehler zu reproduzieren. Dann findest du meist den Fehler bereits selber - und wenn nicht, dann kannst du genau diesen minimierten Code hier posten um zu erfahren was du falsch machst.



  • Lass mal valgrind drüberlaufen.

    Bei mir beschwert sich valgrind u.a. über folgende Zeilen:

    //Z. 119:
    blochstates[j][Tcyclenumber] = Tcycle[j%Tcycle.size()];
    
    //Z. 174
    if(blochstates[q][l] == blochstates[w][l])
    
    //Z. 187
    Energy += 1.0/(sqrt(normleft*normright)) * H(blochstates[q][j], blochstates[w][l], dim, n, J, B) * polar(1.0, 2.0*M_PI*k*(w-q)/static_cast<double>(n));
    

    Womöglich liegt hier ein off-by-one-Fehler vor.

    Edit: definiere bei solchen Problemen auch _GLIBCXX_DEBUG.
    Dann hat dein Programm zu Zeile 119 auch noch folgendes zu sagen:

    /usr/include/c++/4.4/debug/vector:265:error: attempt to subscript container
    with out-of-bounds index 1, but container only holds 1 elements.



  • Vielen, vielen Dank!
    Es funktioniert jetzt (auch wenn ich den eigentlichen Fehler nicht finden konnte).
    Hab aus dem vectorarray "blochstates" jetzt ein normales Array gemacht und es funktioniert! Was da jetzt aber genau schiefgelaufen ist, weiß ich leider nicht.
    Aber Danke für den Tipp mit Valgrind, das ist echt super!
    Echt klasse Forum.



  • Ich möchte ganz energisch darauf hinweisen, dass du das Problem damit nicht gelöst hast. Die ungültigen Arrayzugriffe finden immer noch statt und werden sicher bald wieder zu falschen Ergebnissen oder Programmabstürzen führen.
    Dadurch, dass du den Vektor durch ein Array ersetzt hast, hast du lediglich sowohl der Standardlibrary wie auch valgrind jede Möglichkeit genommen, den Fehler zu erkennen.


Anmelden zum Antworten