Segfault debugging in einem Backtrackalgorithmus
-
volkard schrieb:
PS: Der Ram-Verbrauch liegt bei ca 500MB, gibt es da eine limitierung welches einen solchen Fehler hervorrufen könnte?
Kann schon sein. Aber dann sollte eine Exception fliegen.
Leider wird ja kein Betriebssystem genannt, aber Linux kann je nach kernel Einstellung mehr Speicher zuteilen, als verfügbar ist (Stichwort overcommit). Wenn dann darauf zugegriffen wird, kann auch ein SIGSEG folgen. Wenn aber immer an der gleichen Stelle Schluss ist, würde ich diese Möglichkeit eher ausschließen.
-
Jud4s schrieb:
ca 1700 Rekursionen lang bis das Problem Auftritt.
Ziemlich viele. Stackoverflow?
-
Gibt es Möglichkeiten eure Ideen zu verifizieren? Ich benutze ein Linux Ubuntu und habe ca 4gb frei, allerdings kommt der Fehler an der gleichen Stelle auch auf meinem Netbook (gleiches OS) mit nur 1gb. Allerdings ist es eine solch uninterressante Methode (eine getter Methode) das ich eigentlich einen Logikfehler auf meiner Seite ausschließe. Zumal diese Methode ca 3 mal pro Rekursionsschritt aufgerufen wird, dem entsprechend den Unittest definitiv bestanden haben sollte, bei 1700 Rekursionen, genau wie alle anderen Methoden. Mit fällt einfach kein möglicher Fehler ein bei dem ein Fehler erst so spät auftreten kann, da bei jedem Rekursionsschritt gleich gearbeitet wird.
Bzgl. des Speicherverbrauchs probier ich jetzt mal statt Integern Shorts zu verwenden um das ein bischen zu verringern, sollte es am speicherverbrauch liegen müsste der Fehler zumindestens dann leicht verzögert auftreten.
Danke schonmal für eure Vorschläge.
€: Ja die Abbruchbedingung ist die Lösung des Problems, bzw. ein Schritt zurück erfolgt dann, wenn absehbar ist das der aktuell gewählte Weg nicht zu einer Lösung führen kann, ansonsten dürfte die Rekursionstiefe von der komplexität des Problems begrenzt sein die aktuell bei 2300 liegt.
-
Die Verwendung von Shorts scheint es nicht gebracht zu haben. Der Fehler kommt an der gleichen Stelle allerdings habe ich jetzt mal meinen gdb bemüht und bin zu folgender Ausgabe gelangt:
Program received signal SIGSEGV, Segmentation fault. 0x000000000040b7da in Town::get_cur_capacity (this=0x61efe0) at ./solver/Darstellung.cpp:54 54 return left_over_capacity; (gdb) print 0x61efe0 $1 = 6418400 (gdb) print *0x61efe0 Cannot access memory at address 0x61efe0 (gdb)Mein Betriebssystem benutzt 64-Bit, falls das relevant sein könnte.
-
Jud4s schrieb:
Bzgl. des Speicherverbrauchs probier ich jetzt mal statt Integern Shorts zu verwenden um das ein bischen zu verringern, sollte es am speicherverbrauch liegen müsste der Fehler zumindestens dann leicht verzögert auftreten.
Nicht sicher. Ich kenne deinen Code nicht. Wenn Du viele ints in einem vector hast oder einem anderen Array, dann müßte es verzägern. Wenn Du nur kleine Objekte hast, kann es sein, daß Du zusammen mit einer mal geschätzen allocation granularity von 32 gar keinen Unterschied hast. Und Du hast natürlich keinen Unterschied, wenn Du sowas wie
struct Knoten{ short wert; vector<Knoten> childs; };hast, weil daraus bestimmt
struct Knoten{ short wert; char geheimerAuffueller[2];//ist üblich vector<Knoten> childs;//um den hier auf eine durch 4 teilbare Adresse zu //setzen, weil der Zugriff drauf schneller ist };
-
Jud4s schrieb:
Gibt es Möglichkeiten eure Ideen zu verifizieren?
Du könntest mal die Größe des Stacks erhöhen und dann schauen, ob der Fehler immer noch auftritt.
Jud4s schrieb:
Allerdings ist es eine solch uninterressante Methode (eine getter Methode) das ich eigentlich einen Logikfehler auf meiner Seite ausschließe.
Die kann ja auch korrekt sein. Aber wenn das Objekt auf dem die Funktion aufgerufen wird ungültig ist, gibt es trotzdem in dieser Funktion einen Fehler. Das heißt der Fehler kann überall liegen. Einen Logikfehler kannst du also nicht ausschließen.
-
Wenn es ein einfacher Stackoverflow ist, hilft evtl. -fsplit-stack
(Wobei ich nicht weiß, ob die gcc- und binutilsversionen in Ubuntu aktuell genug sind).
-
kleines update in der Hoffnung das es neue Ideen einbring:
Ich habe nun den Algorithmus iterativ gelöst, um der Möglichkeit vor zu beugen das der Programmstack aufgebraucht wird. Nun allerdings renn ich wieder in einen SIGEGV welcher aber an einer anderen Stelle auftritt, in dem sort Algorithmus der Standartbibliothek:
Program received signal SIGSEGV, Segmentation fault. 0x000000000040b2a0 in Town::get_cur_capacity (this=0x0) at ./solver/Darstellung.cpp:98 98 return left_over_capacity; (gdb) backtrace #0 0x000000000040b2a0 in Town::get_cur_capacity (this=0x0) at ./solver/Darstellung.cpp:98 #1 0x000000000040b9ab in Town::compare_by_capacity (eins=0x0, zwei=0x0) at ./solver/Darstellung.cpp:135 #2 0x00000000004124c7 in std::__move_median_first<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> (__a=..., __b=..., __c=..., __comp=0x40b98e <Town::compare_by_capacity(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:108 #3 0x0000000000411250 in std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> (__first=..., __last=..., __comp=0x40b98e <Town::compare_by_capacity(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:2260 #4 0x000000000040f111 in std::__introsort_loop<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, long, bool (*)(Town const*, Town const*)> (__first=..., __last=..., __depth_limit=21, __comp=0x40b98e <Town::compare_by_capacity(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:2302 #5 0x000000000040de63 in std::sort<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> (__first=..., __last=..., __comp=0x40b98e <Town::compare_by_capacity(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:5250 #6 0x000000000040ce5a in Solution_Stack::get_towns_by_capacity (this=0x7fffffffe010) at ./solver/Darstellung.cpp:331 #7 0x000000000040a6cf in solver::treat_towns_with_zero_capacity (ptr=0x7fffffffe010) at ./solver/Solver.cpp:184 #8 0x0000000000409ff2 in solver::solve_problem (ptr=0x7fffffffe010) at ./solver/Solver.cpp:94 #9 0x000000000041475f in main (argc=3, argv=0x7fffffffe208) at ./main/Main.cpp:50Dafür wurde mir vorgeschlagen eine Check-Funktion zu implementieren welche probiert 0ptr in meinem Vector zu verfolgen und bei auffinden selbiger alarm zu schlagen. Dies brachte mich nur bedingt weiter,das Programm stürtzte immernoch ab:
#0 0x000000000040b2a0 in Town::get_cur_capacity (this=0x40) at ./solver/Darstellung.cpp:98 #1 0x000000000040b9e9 in Town::compare_by_index (eins=0x40, zwei=0x73b4d0) at ./solver/Darstellung.cpp:139 #2 0x000000000040bad1 in Town::compare_by_index_inv (eins=0x40, zwei=0x73b4d0) at ./solver/Darstellung.cpp:153 #3 0x00000000004127ea in std::__unguarded_partition<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, Town*, bool (*)(Town const*, Town const*)> ( __first=..., __last=..., __pivot=@0x631ef0, __comp=0x40baae <Town::compare_by_index_inv(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:2229 #4 0x0000000000411444 in std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> ( __first=..., __last=..., __comp=0x40baae <Town::compare_by_index_inv(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:2261 #5 0x000000000040f2c5 in std::__introsort_loop<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, long, bool (*)(Town const*, Town const*)> ( __first=..., __last=..., __depth_limit=7, __comp=0x40baae <Town::compare_by_index_inv(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:2302 #6 0x000000000040e017 in std::sort<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> (__first=..., __last=..., __comp=0x40baae <Town::compare_by_index_inv(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:5250 #7 0x000000000040d1e6 in Solution_Stack::get_partners_of_by_index_inv (this=0x7fffffffe010, id=523) at ./solver/Darstellung.cpp:371 #8 0x000000000040a4d7 in solver::treat_towns_considering_their_index (ptr=0x7fffffffe010) at ./solver/Solver.cpp:165 #9 0x000000000040a016 in solver::solve_problem (ptr=0x7fffffffe010) at ./solver/Solver.cpp:100 #10 0x0000000000414913 in main (argc=3, argv=0x7fffffffe208) at ./main/Main.cpp:50Danach bin ich mit Valgrind dran und habe folgenden output erhalten, der aber erst beim Fehler an sich auftrat:
==16150== Invalid read of size 4 ==16150== at 0x40B2A0: Town::get_cur_capacity() const (Darstellung.cpp:98) ==16150== by 0x40B9AA: Town::compare_by_capacity(Town const*, Town const*) (Darstellung.cpp:135) ==16150== by 0x4124C6: void std::__move_median_first<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:108) ==16150== by 0x41124F: __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > > std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:2260) ==16150== by 0x40F110: void std::__introsort_loop<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, long, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, long, bool (*)(Town const*, Town const*)) (stl_algo.h:2302) ==16150== by 0x40DE62: void std::sort<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:5250) ==16150== by 0x40CE59: Solution_Stack::get_towns_by_capacity() (Darstellung.cpp:331) ==16150== by 0x40A6CE: solver::treat_towns_with_zero_capacity(Solution_Stack*) (Solver.cpp:184) ==16150== by 0x409FF1: solver::solve_problem(Solution_Stack*) (Solver.cpp:94) ==16150== by 0x41475E: main (Main.cpp:50) ==16150== Address 0x8 is not stack'd, malloc'd or (recently) free'd ==16150== ==16150== ==16150== Process terminating with default action of signal 11 (SIGSEGV) ==16150== Access not within mapped region at address 0x8 ==16150== at 0x40B2A0: Town::get_cur_capacity() const (Darstellung.cpp:98) ==16150== by 0x40B9AA: Town::compare_by_capacity(Town const*, Town const*) (Darstellung.cpp:135) ==16150== by 0x4124C6: void std::__move_median_first<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:108) ==16150== by 0x41124F: __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > > std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:2260) ==16150== by 0x40F110: void std::__introsort_loop<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, long, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, long, bool (*)(Town const*, Town const*)) (stl_algo.h:2302) ==16150== by 0x40DE62: void std::sort<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)>(__gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, __gnu_cxx::__normal_iterator<Town**, std::vector<Town*, std::allocator<Town*> > >, bool (*)(Town const*, Town const*)) (stl_algo.h:5250) ==16150== by 0x40CE59: Solution_Stack::get_towns_by_capacity() (Darstellung.cpp:331) ==16150== by 0x40A6CE: solver::treat_towns_with_zero_capacity(Solution_Stack*) (Solver.cpp:184) ==16150== by 0x409FF1: solver::solve_problem(Solution_Stack*) (Solver.cpp:94) ==16150== by 0x41475E: main (Main.cpp:50) ==16150== If you believe this happened as a result of a stack ==16150== overflow in your program's main thread (unlikely but ==16150== possible), you can try to increase the size of the ==16150== main thread stack using the --main-stacksize= flag. ==16150== The main thread stack size used in this run was 8388608. ==16150== ==16150== HEAP SUMMARY: ==16150== in use at exit: 771,174 bytes in 19,239 blocks ==16150== total heap usage: 9,821,251 allocs, 9,802,012 frees, 384,861,557 bytes allocated ==16150== ==16150== 50,678 bytes in 1,491 blocks are possibly lost in loss record 28 of 35 ==16150== at 0x4C28B42: operator new(unsigned long) (vg_replace_malloc.c:261) ==16150== by 0x4ECBE6C: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.14) ==16150== by 0x4ECC08D: std::string::_M_mutate(unsigned long, unsigned long, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.14) ==16150== by 0x4ECC730: std::string::erase(unsigned long, unsigned long) (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.14) ==16150== by 0x407FB6: utility::split_helper(std::string, std::string) (Tools.cpp:28) ==16150== by 0x4080B5: utility::split_helper(std::string, std::string) (Tools.cpp:49) ==16150== by 0x4081C3: utility::split(std::string, std::string) (Tools.cpp:66) ==16150== by 0x40539C: parser::get_city_prototypes(std::vector<std::string, std::allocator<std::string> >) (Parser.cpp:27) ==16150== by 0x4050EB: parser::get_problem_configuration(std::string, std::string) (Parser.cpp:17) ==16150== by 0x414699: main (Main.cpp:34) ==16150== ==16150== 62,606 (11,928 direct, 50,678 indirect) bytes in 1,491 blocks are definitely lost in loss record 30 of 35 ==16150== at 0x4C28B42: operator new(unsigned long) (vg_replace_malloc.c:261) ==16150== by 0x407F68: utility::split_helper(std::string, std::string) (Tools.cpp:24) ==16150== by 0x4080B5: utility::split_helper(std::string, std::string) (Tools.cpp:49) ==16150== by 0x4081C3: utility::split(std::string, std::string) (Tools.cpp:66) ==16150== by 0x40539C: parser::get_city_prototypes(std::vector<std::string, std::allocator<std::string> >) (Parser.cpp:27) ==16150== by 0x4050EB: parser::get_problem_configuration(std::string, std::string) (Parser.cpp:17) ==16150== by 0x414699: main (Main.cpp:34) ==16150== ==16150== 94,406 (18,440 direct, 75,966 indirect) bytes in 2,305 blocks are definitely lost in loss record 32 of 35 ==16150== at 0x4C28B42: operator new(unsigned long) (vg_replace_malloc.c:261) ==16150== by 0x407F68: utility::split_helper(std::string, std::string) (Tools.cpp:24) ==16150== by 0x4080B5: utility::split_helper(std::string, std::string) (Tools.cpp:49) ==16150== by 0x4081C3: utility::split(std::string, std::string) (Tools.cpp:66) ==16150== by 0x40573F: parser::get_finished_cities(std::vector<std::string, std::allocator<std::string> >, std::vector<City*, std::allocator<City*> >) (Parser.cpp:42) ==16150== by 0x40511A: parser::get_problem_configuration(std::string, std::string) (Parser.cpp:17) ==16150== by 0x414699: main (Main.cpp:34) ==16150== ==16150== 178,720 (131,208 direct, 47,512 indirect) bytes in 1,491 blocks are definitely lost in loss record 35 of 35 ==16150== at 0x4C28B42: operator new(unsigned long) (vg_replace_malloc.c:261) ==16150== by 0x40541B: parser::get_city_prototypes(std::vector<std::string, std::allocator<std::string> >) (Parser.cpp:28) ==16150== by 0x4050EB: parser::get_problem_configuration(std::string, std::string) (Parser.cpp:17) ==16150== by 0x414699: main (Main.cpp:34) ==16150== ==16150== LEAK SUMMARY: ==16150== definitely lost: 161,576 bytes in 5,287 blocks ==16150== indirectly lost: 174,156 bytes in 5,287 blocks ==16150== possibly lost: 50,678 bytes in 1,491 blocks ==16150== still reachable: 384,764 bytes in 7,174 blocks ==16150== suppressed: 0 bytes in 0 blocks ==16150== Reachable blocks (those to which a pointer was found) are not shown. ==16150== To see them, rerun with: --leak-check=full --show-reachable=yes ==16150== ==16150== For counts of detected and suppressed errors, rerun with: -v ==16150== Use --track-origins=yes to see where uninitialised values come from ==16150== ERROR SUMMARY: 7 errors from 7 contexts (suppressed: 4 from 4)
-
Nun ja, wie gdb schreibt:
#1 0x000000000040b9e9 in Town::compare_by_index ([b]eins=0x40[/b], zwei=0x73b4d0) at ./solver/Darstellung.cpp:139Ich kann mir nicht vorstellen, dass 0x40 eine gültige Instanz von Town enthält; vielmehr sieht mir das so aus, als sei ein Null-Zeiger als Array interpretiert worden.
-
Ja nur wo kommt der her? Ich habe mitlerweile eine Methode implementiert die nach jedem zugriff, insbesondere veränderung der Elemente des Vectors eine überprüfung auf NULLpointer macht, aber die schlägt nicht an.
Ich denke das unterstützt deine These auch, aber die essentielle frage nach dem Grund ist immernoch im dunklen.
Program received signal SIGSEGV, Segmentation fault. 0x000000000040b2f0 in Town::get_cur_capacity (this=0x7fff00000000) at ./solver/Darstellung.cpp:98 98 return left_over_capacity; (gdb) print this $1 = (const Town * const) 0x7fff00000000 (gdb) pring *0x7fff00000000 Undefined command: "pring". Try "help". (gdb) print *0x7fff00000000 Cannot access memory at address 0x7fff00000000 (gdb) backtrace #0 0x000000000040b2f0 in Town::get_cur_capacity (this=0x7fff00000000) at ./solver/Darstellung.cpp:98 #1 0x000000000040ba39 in Town::compare_by_index (eins=0x7fff00000000, zwei=0x71af90) at ./solver/Darstellung.cpp:139 #2 0x000000000040bb21 in Town::compare_by_index_inv (eins=0x7fff00000000, zwei=0x71af90) at ./solver/Darstellung.cpp:153 #3 0x00000000004128b4 in std::__unguarded_partition<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, Town*, bool (*)(Town const*, Town const*)> ( __first=..., __last=..., __pivot=@0x62d2d0, __comp=0x40bafe <Town::compare_by_index_inv(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:2229 #4 0x000000000041150e in std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> ( __first=..., __last=..., __comp=0x40bafe <Town::compare_by_index_inv(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:2261 #5 0x000000000040f38f in std::__introsort_loop<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, long, bool (*)(Town const*, Town const*)> ( __first=..., __last=..., __depth_limit=7, __comp=0x40bafe <Town::compare_by_index_inv(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:2302 #6 0x000000000040e0e1 in std::sort<__gnu_cxx::__normal_iterator<Town**, std::vector<Town*> >, bool (*)(Town const*, Town const*)> (__first=..., __last=..., __comp=0x40bafe <Town::compare_by_index_inv(Town const*, Town const*)>) at /usr/include/c++/4.5/bits/stl_algo.h:5250 #7 0x000000000040d2b0 in Solution_Stack::get_partners_of_by_index_inv (this=0x7fffffffdff0, id=523) at ./solver/Darstellung.cpp:373 #8 0x000000000040a527 in solver::treat_towns_considering_their_index (ptr=0x7fffffffdff0) at ./solver/Solver.cpp:165 #9 0x000000000040a066 in solver::solve_problem (ptr=0x7fffffffdff0) at ./solver/Solver.cpp:100 #10 0x0000000000414aa5 in main (argc=3, argv=0x7fffffffe208) at ./main/Main.cpp:61
-
Du hast auf jeden Fall sehr merkwürdige Zeigerwerte im Vektor - im Zweifel bedeutet das eins von zwei Dingen: Entweder, du stopfst kaputte Zeiger in den Vektor, oder du zerschießt dir an anderer Stelle den Speicher, wo der Vektor liegt (vermutlich den Stack).
Im ersten Fall könnte es dir helfen, die Zeiger zu prüfen, bevor du sie in den Vektor stopfst. Im zweiten Fall würde ich es mal mit -fmudflap -lmudflap versuchen. Allerdings ist Mudflap mit C++-Code insofern suboptimal, als dass viele false-positives auftreten (gerade mit STL-Containern) - die Stellen, die er anmeckert, kann man durchkucken, ob einem da etwas auffällt, aber nicht alles, was Mudflap anmeckert, ist auch fehlerhaft.
Ohne Code kann ich mehr dazu nicht sagen.
-
Es ist kein Problem code zu posten, nur das Program hat ein paar Zeilen und ich will nicht randommäßig Code veröffentlichen. Aber wenn ihr mir sagen könnt welcher Code relevant ist würde ich sicherlich die stellen zeigen.
-
Ich habe die (vermutlich) relevanten Codestellen rausgesucht die die Objekte im Vektor manipulieren, alle anderen stellen die auf den verdächtigen Vektor zugreifen sind const deklariert.
Der Vektor heißt layer und besteht aus Zeigern aus ptr to Town obj.
Die Town Klasse
//Die Konstruktoren Town::Town(int id,int capa, std::vector<int> buddies) throw(err): ID(id), start_capacity(capa), left_over_capacity(capa), partner_towns(buddies), partner_towns_partied(), partner_towns_partying(){ } Town::Town(const Town* to_copy,int host, int guest,bool forward) throw(err): ID(to_copy->get_id()), start_capacity(to_copy->get_start_capacity()), partner_towns(to_copy->get_partner_towns()), partner_towns_partied( to_copy->get_partner_towns_partied() ), partner_towns_partying( to_copy->get_partner_towns_partying() ), left_over_capacity(to_copy->get_cur_capacity()){ if(ID == host && forward) { //logger::Infolog("Got one"); this->left_over_capacity -= 1; //logger::Infolog("Kapacity down to " + utility::int_to_string(left_over_capacity) ); partner_towns_partied.push_back(guest); } if(ID == guest && forward) { partner_towns_partying.push_back(host); } if(ID == host && !forward) { this->left_over_capacity += 1; for(std::vector<int>::iterator iter = partner_towns_partied.begin(); iter != partner_towns_partied.end(); ++iter) { if(*iter == guest) { partner_towns_partied.erase(iter); break; } } } if(ID == guest && !forward) { for(std::vector<int>::iterator iter = partner_towns_partied.begin(); iter != partner_towns_partied.end(); ++iter) { if(*iter == host) { partner_towns_partied.erase(iter); break; } } } }Die Wrapper-Klasse die ich um den Vektor mit den Town Objekten gemacht habe heißt Solution_Stack
//Der Konstruktor Solution_Stack::Solution_Stack(std::vector<City*> parsed) throw(err) { std::vector<Town*> beginners; for(int i = 0; i != parsed.size(); ++i) id_name.push_back( std::pair<std::string,int>(parsed[i]->get_name(),i) ); for(int i = 0; i != parsed.size(); ++i) { std::vector<int> buddies; for(int x = 0; x != parsed[i]->get_friends()->size(); ++x) buddies.push_back(name_to_id( (*parsed[i]->get_friends())[x] ) ); beginners.push_back(new Town(i, (int)parsed[i]->get_capacity(), buddies ) ); } layer = beginners; }Die Methode die den Inhalt des Vektor verändern
void Solution_Stack::execute_order(int host,int guest) throw(err) { rlimit limit; getrlimit(RLIMIT_STACK,&limit); std::cout << "rlim_cur ist :" << limit.rlim_cur << std::endl; std::cout << "rlim_max ist :" << limit.rlim_max << std::endl; static short counter = 1; logger::Infolog("execute order " + utility::int_to_string(counter) + " - host: " + id_to_name(host) + "/guest: " + id_to_name(guest)); ++counter; order_layer.push(new std::pair<int,int>(host,guest) ); std::vector<Town*> next_layer; const std::vector<Town*>* current_layer = this->get_towns(); for(int i = 0; i != current_layer->size(); ++i) next_layer.push_back(new Town( (*current_layer)[i],host,guest,true)); for(int i = 0; i != current_layer->size();++i) { //std::cout << i << std::endl; delete (*current_layer)[i]; } layer = next_layer; check_vec(); } void Solution_Stack::redo_last_order() throw(err) { logger::Infolog("redoing last order"); //layers.pop_back(); const std::vector<Town*>* current_layer = this->get_towns(); std::vector<Town*> next_layer; next_layer.resize( current_layer->size() + 1 ); //layers.push_back(next_layer); for(int i = 0; i != current_layer->size(); ++i) next_layer.push_back(new Town( (*current_layer)[i], (*order_layer.top()).first, (*order_layer.top()).second, false) ); for(int i = 0; i != layer.size(); ++i) delete layer[i]; layer = next_layer; order_layer.pop(); if(order_layer.empty()) { throw err("problem seems unsolveable, killed last remaining layer"); } check_vec(); }Die Methoden die auf den vector zugreifen
const std::vector<Town*>* Solution_Stack::get_towns_by_capacity() { std::sort(layer.begin(),layer.end(),&Town::compare_by_capacity); check_vec(); return &layer; } const std::vector<Town*>* Solution_Stack::get_towns_by_index() { std::sort(layer.begin(),layer.end(), &Town::compare_by_index); check_vec(); return &layer; } std::vector<int> Solution_Stack::get_partners_of_by_index_inv(int id) { //gehe alle Städte durch for(int i = 0; i != layer.size(); ++i) { //und finde die entsprechende Stadt if(layer[i]->get_id() == id) { std::vector<Town*> buddies; for(int x = 0; x != layer[i]->get_partner_towns().size(); ++x){ for(int p = 0; p != layer.size(); ++p) { if(layer[p]->get_id() == layer[i]->get_partner_towns()[x]) buddies.push_back(layer[p]); } } //mysort(&buddies,&Town::compare_by_index_inv); for(int p = 0; p != buddies.size(); ++p) std::cout << buddies[p] << std::endl; std::sort(buddies.begin(),buddies.end(),&Town::compare_by_index_inv); std::vector<int> ret; for(int x = 0; x != buddies.size(); ++x) ret.push_back(buddies[x]->get_id()); check_vec(); return ret; } } }