std::sort: woher nichtinitialisierter Wert?
-
Hallo,
ich mochte ein Objekt mittels std::sort sortieren.
Dazu habe ich die Funktionfriend bool greater_lex(const Atom& a1, const Atom& a2);, die in der Klasse Nucleotide, die einen std::vector<Atom> enthaelt, mittels
void sort_lex() {std::sort(atoms_.begin(), atoms_.end(), greater_lex);benutzt werden soll.
Die endet mit einem Segmentation fault, und zwar, wie ich glaube, weil greater_lex auf einen nichtinitialisierten String zugreift (behaupten u.a. valgrind und gdb).
Meine Frage ist nun: Wo kommt mein uninitialisiertes Atom her?Die Klasse Atom enthaelt einen default-Konstruktor, drei Konstruktoren mit Argumenten, einen copy-Konstruktor und einen assignment-operator, wobei die letzten beiden m.E. nicht notwendig sind, da die Daten keine Zeiger sind. Der Konstruktor ist dementsprechend leer:
virtual ~Atom(){};Bei der einzigen bgeleiteten Klasse verhaelt es sich ebenso. In allen Konstruktoren und im operator= werden alle Daten initialisiert, bzw. beruecksichtigt, soweit ich das sehen kann.
Das einzige, wo ich mich nicht sicher fuehle, ist der Effekt des virtuellen Destruktors.Uebersehe ich eine Moeglichkeit, wie es zu einem nicht-initialisierten Atom kommen kann?
Falls es jemandem etwas bringt, ein Auszug aus valgrind, der mit leider nicht weitergeholfen hat, ausser das das 'delete' im 2. Block darauf hinweisen koennte, dass ich was beim Destruktor falsch gemacht haben koennte:
[...] ==1698== Invalid read of size 4 ==1698== at 0x817F77F: lesser_lex(Atom const&, Atom const&) (nucleotide.cpp:33) ==1698== by 0x82331F7: greater_lex(Atom const&, Atom const&) (nucleotide.h:43) ==1698== by 0x8233832: _ZSt21__unguarded_partitionISt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIP4AtomSt6vectorIS3_SaIS3_EEEEES3_PFbRKS3_SB_EET_SE_SE_T0_T1_ (stl_algo.h:1912) ==1698== by 0x8233669: _ZSt16__introsort_loopISt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIP4AtomSt6vectorIS3_SaIS3_EEEEEiPFbRKS3_SB_EEvT_SE_T0_T1_ (stl_algo.h:2149) ==1698== by 0x82336EE: _ZSt16__introsort_loopISt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIP4AtomSt6vectorIS3_SaIS3_EEEEEiPFbRKS3_SB_EEvT_SE_T0_T1_ (stl_algo.h:2150) ==1698== by 0x8233347: _ZSt4sortISt16reverse_iteratorIN9__gnu_cxx17__normal_iteratorIP4AtomSt6vectorIS3_SaIS3_EEEEEPFbRKS3_SB_EEvT_SE_T0_ (stl_algo.h:2211) ==1698== by 0x8232716: Nucleotide::sort_lex() (nucleotide.h:57) ==1698== by 0x8221EAD: Debug::test_nukleotide() (debug.cpp:331) ==1698== by 0x821E8FE: Debug::debug() (debug.cpp:28) ==1698== by 0x80F0691: main (main.cpp:47) ==1698== Address 0x1BB5542C is 2900 bytes inside a block of size 2944 free'd ==1698== at 0x1B904CA8: operator delete(void*) (vg_replace_malloc.c:155) ==1698== by 0x1B99575B: std::__default_alloc_template<true, 0>::deallocate(void*, unsigned) (in /usr/lib/libstdc++.so.5.0.7) ==1698== by 0x8067412: std::__simple_alloc<Atom, std::__default_alloc_template<true, 0> >::deallocate(Atom*, unsigned) (stl_alloc.h:242) ==1698== by 0x80673DF: std::_Vector_alloc_base<Atom, std::allocator<Atom>, true>::_M_deallocate(Atom*, unsigned) (stl_vector.h:130) ==1698== by 0x813CB13: std::vector<Atom, std::allocator<Atom> >::_M_insert_aux(__gnu_cxx::__normal_iterator<Atom*, std::vector<Atom, std::allocator<Atom> > >, Atom const&) (vector.tcc:254) ==1698== by 0x813C015: std::vector<Atom, std::allocator<Atom> >::push_back(Atom const&) (stl_vector.h:603) ==1698== by 0x817FF3A: Nucleotide::Nucleotide(std::vector<Molekel, std::allocator<Molekel> >&, std::vector<Atom, std::allocator<Atom> >&, int) (nucleotide.cpp:99) ==1698== by 0x8221DED: Debug::test_nukleotide() (debug.cpp:328) ==1698== by 0x821E8FE: Debug::debug() (debug.cpp:28) ==1698== by 0x80F0691: main (main.cpp:47) [...]Falls notwendig, schicke ich gerne Code mit, doch dachte ich, dass die angegebnenen Informationen erstmal fuer einen Tip ausreichend sein koennten, bevor ich seitenweise Code einfuege.
Vielen Dank fuer alle Hinweise!
-
Ich schaetze, ich habe den Fehler gefunden. Im Konstruktor habe ich ein std::copy falsch verwendet, d.h., ohne back_inserter, so dass es einen Zeiger auf 0 im vector gab. Zumindest erzeuge ich nun keinen SegFault mehr.