Segmentation fault
-
Hello,
I have a segmentation fault that I really don't understand even with the debugger, I know where the problem is but I can't see what's the problem at all xD
To resume :
I have two pokemons of the class Pokemon
Those pokemons have four capacities :Capacity *m_capacity_1; Capacity *m_capacity_2; Capacity *m_capacity_3; Capacity *m_capacity_4;
And one active capacity :
Capacity *m_active_capacity;
After creating my two pokemons, I want the first one to attack the second so I have some functions in my class Pokemon :
Capacity* Pokemon::get_active_capacity() const { return m_active_capacity; } void Pokemon::set_active_capacity(Capacity const& capacity) { delete m_active_capacity; m_active_capacity = new Capacity(capacity); //Calling the copy constructor that works well }
And before attacking I set the active_capacity of the attacker because it's the one he's gonna use :
pokemon_1->set_active_capacity(*(pokemon_1->get_capacity(1)));
And this works BUT the problem I have is that I want to do the above command when I click on the capacity button so I created a connection with my button :
QObject::connect(m_button_capacity_1, &QPushButton::released, this, [=]() { pokemon_1->set_active_capacity(*(pokemon_1->get_capacity(1))); });
The thing that I don't understand is that this line works if I call it directly in my code but if I try to call it in the connect above, it create a segmentation fault :/
Any idea ? :)
-
@Tequiloutre said in Segmentation fault:
BUT if I call it in a
connect
function like this :QObject::connect(m_button_capacity_1, &QPushButton::released, this, [=]() { pokemon_1->set_active_capacity(*(pokemon_1->get_capacity(1))) ; });
I get a segmentation fault.
How is pokemon_1 allocated? Is it possible that it has been destroyed or moved by the time the button has been clicked?
-
@Tequiloutre
Verify whatpokemon_1
andpokemon_1->get_capacity(1)
return in your lambda. And look at what the stack trace is showing you in the debugger --- you can even go up levels and see the value of stuff there. And/or, put breakpoints in the methods you show. -
Indeed, it seems to have a problem in the lambda.
I've just asked to qDebug pokemon_1 in the connect, and I get it but all the values are wrong :pokemon_1 @0x5555559e1050 Pokemon m_active_capacity @0x5555559f0000 Capacity m_att 3145776 int m_att_spe 3145783 int m_capacity_1 0x30003200370064 Capacity* m_capacity_2 0x30003000300030 Capacity* m_capacity_3 0x30003000330038 Capacity* m_capacity_4 0x30003000300030 Capacity* m_def 3145776 int m_def_spe 3145776 int m_etat <inaccessible> QString m_ev_att 3145776 int m_ev_att_spe 3145776 int m_ev_def 3145776 int m_ev_def_spe 3145777 int m_ev_hp 3145776 int m_ev_vit 3145776 int m_gender <inaccessible> QString m_hp 2293805 int m_hpMax 6684774 int m_id 1 int m_iv_att 3145776 int m_iv_att_spe 3145776 int m_iv_def 3145776 int m_iv_def_spe 3145776 int m_iv_hp 3145776 int m_iv_vit 3145776 int m_lvl 7209071 int m_name <inaccessible> QString m_nature <inaccessible> QString m_type_1 <inaccessible> QString m_type_2 <inaccessible> QString m_vit 3145776 int
But I can't understand why ?
Why does the lambda doesn't get the right values ? :o -
@Tequiloutre said in Segmentation fault:
Those pokemons have four capacities :
Capacity *m_capacity_1;
Capacity *m_capacity_2;
Capacity *m_capacity_3;
Capacity *m_capacity_4;And one active capacity :
Capacity *m_active_capacity;Maybe there is a reason why you do this, but I would re-design this structure and create one container with all four capacities and add a
bool isActive
toCapacity
class.You can get your active one by iterating the container and check the
active state
at the same time. Then just return the active one. -
Thank you for your advice but in the end I would still have to use a function in my
connect
to recover the capacity, and I would come back to the same problem, right ?I think I've understand wrong the debugger, I've watched the values at the beginning of my app, just after the creation of the
pokemon_1
and the values showed in the debugger are wrong too but if I print the values in the console with my functions they're right. So I just don't understand the debugger xDBut the problem seems to be
void Pokemon::set_active_capacity(Capacity const& capacity) { delete m_active_capacity; //<= this line m_active_capacity = new Capacity(capacity); }
The thing that I really don't understand is why those commands works when called in
main window
but not when called inconnect
function ?Debugger stack traces (don't know if it helps) :
1 std::__atomic_base<int>::load 2 QAtomicOps<int>::loadRelaxed<int> 3 QBasicAtomicInteger<int>::loadRelaxed 4 QPrivate::RefCount::deref 5 QString::~QString 6 Capacity::~Capacity 7 Pokemon::set_active_capacity 8 Window::<lambda()>::operator()(void) const ...
-
Then don't delete the old pointer here and simply assign the value. Maybe don't even store a pointer but an object as member.
-
I change some things as you advised :
void Pokemon::set_active_capacity(Capacity* capacity) { m_active_capacity = capacity; }
Then I call it with the button connect like this :
QObject::connect(m_button_capacity_1, &QPushButton::released, this, [=]() { pokemon_1->set_active_capacity(pokemon_1->get_capacity(1)) ; });
And it seems to work BUT I think it just gets around the problem because I have the same segmentation fault just after that with the simple command :
pokemon_1->get_name();
I think the reason is just that I don't use the lambda (that I really don't know much) correctly because as I said before, all of the
Pokemon
class functions works well when called directly in the program but doesn't work when called in theconnect
function.For exemple :
qDebug() << "pokemon_1.active_capacity : " << pokemon_1->get_active_capacity()->get_name(); pokemon_1->set_active_capacity(*(pokemon_1->get_capacity(1))); qDebug() << "pokemon_1.active_capacity : " << pokemon_1->get_active_capacity()->get_name();
Returns :
pokemon_1.active_capacity : /*Nothing because I create it with an empty name in the Pokemon constructor*/ pokemon_1.active_capacity : Charge /*The name of pokemon_1.capacity_1 because the set_active_capacity() worked*/
BUT if I call it in a
connect
function like this :QObject::connect(m_button_capacity_1, &QPushButton::released, this, [=]() { pokemon_1->set_active_capacity(*(pokemon_1->get_capacity(1))) ; });
I get a segmentation fault.
-
@Tequiloutre said in Segmentation fault:
BUT if I call it in a
connect
function like this :QObject::connect(m_button_capacity_1, &QPushButton::released, this, [=]() { pokemon_1->set_active_capacity(*(pokemon_1->get_capacity(1))) ; });
I get a segmentation fault.
How is pokemon_1 allocated? Is it possible that it has been destroyed or moved by the time the button has been clicked?
-
@Tequiloutre said in Segmentation fault:
I change some things as you advised :
I did not said this:
and simply assign the value.
The value of the object, not the value of the pointer
-
pokemon_1 is allocated like this :
Pokemon *pokemon_1 = new Pokemon(tortipouss, 5, charge, repli);
It gets the basic values of
tortipouss
and calculate all the stats at lvl 5 and give it the capacitiescharge
andrepli
, all declared before it like this :Capacity charge("Charge", "NORMAL", "PHY", 35, 95, 35, 35, 0); Capacity repli("Repli", "EAU", "STA", 0, 0, 40, 40, 0); Init_Pokemon tortipouss(387, "Tortipouss", "PLANTE", "", 55, 68, 64, 45, 55, 31, 12.5, 87.5);
Then values of pokemon_1 looks like this :
m_id : 387 m_name : "Tortipouss" m_type_1 : "PLANTE" m_type_2 : "" m_gender : "♂" m_lvl : 5 m_hp : 21 m_hp_max : 21 m_etat : "" m_nature : "" m_iv_hp : 18 m_iv_att : 8 m_iv_def : 30 m_iv_att_spe : 16 m_iv_def_spe : 3 m_iv_vit : 9 m_ev_hp : 0 m_ev_att : 0 m_ev_def : 0 m_ev_att_spe : 0 m_ev_def_spe : 0 m_ev_vit : 0 m_att : 12 m_def : 12 m_att_spe : 10 m_def_spe : 10 m_vit : 8 m_capacity_1->get_name() : "Charge" m_capacity_2->get_name() : "Repli" m_capacity_3->get_name() : "" m_capacity_4->get_name() : "" m_active_capacity->get_name() : ""
I get all those values with simple :
qDebug() << "m_name : " << pokemon_1->get_name();
.
.
@Christian-EhrlicherYou mean like this ?
void Pokemon::set_active_capacity(Capacity const& capacity) { *m_active_capacity = capacity; }
I completely changed my program to use m_active_capacity as an object instead of a pointer and finally :
Segmentation fault with the operator= function :Capacity& Capacity::operator=(Capacity const& copy) { if (this != ©) { m_name = copy.m_name; m_type = copy.m_type; m_category = copy.m_category; m_power = copy.m_power; m_aim = copy.m_aim; m_pp = copy.m_pp; m_pp_max = copy.m_pp_max; m_priority = copy.m_priority; } return *this; }
-
OW FFS I hate myself.
@jeremy_k were right.
I'm a beginner with Qt and I've made a stupid mistake.
I told myself "Hey you're creating pokemon_1 as a new pointer so you dynamicaly allocate some memory that have to be freeded at the end of the program haha"
I had those lines at the end of my main_window class definition :
delete pokemon_1; delete pokemon_2;
OF COURSE they're destroyed before I press the button !
SO SORRY about that guys, thank you very much for your time and advices !