c++ g++ segmentation-fault

c++ - g++ produce segfault con compilación normal, pero ninguno con-g



segmentation-fault (3)

La forma en que esto va, parece una falla en el empaquetado / construcción de GCC / libstdc ++, o en la versión utilizada. Pruebe GCC 4.5 o 4.6 y si no ocurre allí, dígale a usted mismo que siempre use lo último y lo mejor (hasta que se rompa algo por supuesto) y nunca mire hacia atrás.

Parece que el compilador no está inicializando el miembro A en B , lo que daría como resultado que el destructor de std::string no pueda leer la información necesaria para autodestruirse. Pero esto es solo conjetura y conjeturas.

Estoy aprendiendo C ++ ahora mismo con "Thinking in C ++" de Bruce Eckel y estoy en los primeros capítulos. Tengo un fondo C y Java. En este momento tengo el siguiente problema: cuando compilo las fuentes a continuación con

g++ A.cpp B.cpp bmain.cpp

, el programa genera un "1" (correctamente) y luego un segfault. Cuando compilo con

g++ -g A.cpp B.cpp bmain.cpp

, el mismo programa exacto produce una segfault de 1 y NO! Debo decir que esto me parece sorprendente. ¿Podría alguien señalar lo que hago mal? Mi SO es "Linux 2.6.35-30-generic # 54-Ubuntu x86_64", mi g ++ es la versión "g ++ (Ubuntu / Linaro 4.4.4-14ubuntu5) 4.4.5".

EDITAR: Solo porque esta parece ser una fuente importante del error, gracias @Evan Teran: ¡El constructor A en la estructura B nunca se llama! He puesto un "cout <<" blah "<< endl;" dentro y no imprime nada

EDITAR: He incluido el "return 0" al final de main ahora, pero eso no ayuda.

Ah:

#ifndef A_H #define A_H #include <string> class A { public: int i; std::string str; void print(); A(); }; #endif

A.cpp:

#include "A.h" #include <iostream> #include <string> using namespace std; void A::print() { cout << str << " " << i << endl; } A::A() { str = "initstr"; i = 0; }

Bh:

#ifndef B_H #define B_H #include "A.h" class B { private: int counter; public: A a; B(); void increase(); int read(); }; #endif

B.cpp:

#include "B.h" using namespace std; B::B() { counter = 0; } void B::increase() { ++counter; } int B::read() { return counter; }

bmain.cpp:

#include <iostream> #include "B.h" using namespace std; int main(int argc, char **argv) { B b; b.increase(); cout << b.read() << endl; return 0; }

EDITAR: He instalado g ++ desde los paquetes. Mi Ubuntu también es muy estándar.

Esto es lo que obtengo cuando llamo a gdb a.out core

warning: Can''t read pathname for load map: Eingabe-/Ausgabefehler. Reading symbols from /usr/lib/libstdc++.so.6...(no debugging symbols found)...done. Loaded symbols for /usr/lib/libstdc++.so.6 Reading symbols from /lib/libm.so.6...Reading symbols from /usr/lib/debug/lib/libm-2.12.1.so...done. done. Loaded symbols for /lib/libm.so.6 Reading symbols from /lib/libgcc_s.so.1...(no debugging symbols found)...done. Loaded symbols for /lib/libgcc_s.so.1 Reading symbols from /lib/libc.so.6...Reading symbols from /usr/lib/debug/lib/libc-2.12.1.so...done. done. Loaded symbols for /lib/libc.so.6 Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug/lib/ld-2.12.1.so...done. done. Loaded symbols for /lib64/ld-linux-x86-64.so.2 Core was generated by `./a.out''. Program terminated with signal 11, Segmentation fault. #0 0x00007fba1049104b in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() () from /usr/lib/libstdc++.so.6

EDIT 2: Por cierto, mi hardware no es defectuoso por lo que sé y trato el sistema operativo bastante bien

EDIT 3: Valgrind informa lo siguiente:

==3428== Conditional jump or move depends on uninitialised value(s) ==3428== at 0x4ECB022: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/libstdc++.so.6.0.14) ==3428== by 0x400D73: A::~A() (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== by 0x400D91: B::~B() (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== by 0x400CD7: main (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== ==3428== Use of uninitialised value of size 8 ==3428== at 0x4ECB04B: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/libstdc++.so.6.0.14) ==3428== by 0x400D73: A::~A() (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== by 0x400D91: B::~B() (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== by 0x400CD7: main (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== ==3428== Invalid read of size 4 ==3428== at 0x4ECB04B: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/libstdc++.so.6.0.14) ==3428== by 0x400D73: A::~A() (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== by 0x400D91: B::~B() (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== by 0x400CD7: main (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== Address 0xfffffffffffffff8 is not stack''d, malloc''d or (recently) free''d ==3428== ==3428== ==3428== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==3428== Access not within mapped region at address 0xFFFFFFFFFFFFFFF8 ==3428== at 0x4ECB04B: std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() (in /usr/lib/libstdc++.so.6.0.14) ==3428== by 0x400D73: A::~A() (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== by 0x400D91: B::~B() (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== by 0x400CD7: main (in /home/xxx/C++/Exercises/ch04/a.out) ==3428== If you believe this happened as a result of a stack ==3428== overflow in your program''s main thread (unlikely but ==3428== possible), you can try to increase the size of the ==3428== main thread stack using the --main-stacksize= flag. ==3428== The main thread stack size used in this run was 8388608. ==3428== ==3428== HEAP SUMMARY: ==3428== in use at exit: 0 bytes in 0 blocks ==3428== total heap usage: 0 allocs, 0 frees, 0 bytes allocated ==3428== ==3428== All heap blocks were freed -- no leaks are possible


Seguramente está invocando un comportamiento indefinido (UB) en algún lugar de su programa. El objetivo de UB es que el comportamiento no solo no está definido, sino que puede cambiar según la plataforma, el compilador, los indicadores, etc. Es probable que la adición de -g perturbe las cosas de tal manera que se evite la segfault, pero eso es solo casualidad.