Results 1 to 11 of 11

Thread: Program crashes when Canon ball reaches "water"

  1. #1
    Join Date
    Mar 2019
    Posts
    22
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Unhappy Program crashes when Canon ball reaches "water"

    So i made a simple game where i protect my island from incoming enemies and at the start u control ship and when you press space you shoot a canon ball and all goes well until my canon ball reaches the point where i delete it.
    I get a segmentation error which i believe means that im trying to reach memory that no longer exists, but still have no idea what is wrong...

    and these are the errors i get:

    error.jpg
    link: https://ddgobkiprc33d.cloudfront.net...b6759bc53e.png

    QGraphicsItem::x

    graphiitem.jpg
    link: https://ddgobkiprc33d.cloudfront.net...5b5438eff2.png

    function inside Canon Class moveCanonBall()

    mvoecanoin.jpg
    link: https://ddgobkiprc33d.cloudfront.net...92fc602e76.png

    and this

    this.jpg
    link: https://ddgobkiprc33d.cloudfront.net...e9062b1a01.png

    This is Canon's header file:
    Qt Code:
    1. #ifndef CANON_H
    2. #define CANON_H
    3.  
    4. #include <QGraphicsItem>
    5. #include <QObject>
    6. #include <QGraphicsPathItem>
    7. #include <QTimer>
    8.  
    9. class Canon: public QObject, public QGraphicsPixmapItem{
    10. Q_OBJECT
    11. public:
    12. Canon(QGraphicsItem *parent=0);
    13. ~Canon();
    14. QTimer *time;
    15. static bool getCanonBallGone();
    16. static bool setCanonBallGoneToFalse();
    17. static bool setCanonBallGoneToTrue();
    18. private:
    19. int direction;
    20. double xPl;
    21. double yPl;
    22. double newX;
    23. double moveByX;
    24. double moveByY;
    25. bool moveDown;
    26. double help;
    27. bool ballHitEnd;
    28. static bool CanonBallGone;
    29. int splashLasting;
    30.  
    31. public slots:
    32. void moveCanonBall();
    33. };
    34.  
    35. #endif // CANON_H
    To copy to clipboard, switch view to plain text mode 

    And this i canon's .cpp file:

    Qt Code:
    1. #include "canon.h"
    2. #include "game.h"
    3. #include "math.h"
    4. #include "soundeffects.h"
    5. #include <QGraphicsPixmapItem>
    6. #include <QPixmap>
    7. #include <QObject>
    8. #include <QTimer>
    9. #include <QDebug>
    10. #include <QMediaPlayer>
    11.  
    12. #include "soundeffects.h"
    13.  
    14. extern Game *game;
    15.  
    16. bool Canon::CanonBallGone=false;
    17.  
    18. Canon::Canon(QGraphicsItem *parent): QGraphicsPixmapItem(parent){
    19.  
    20. ballHitEnd = false;
    21.  
    22. setPixmap(QPixmap(":/Images/Canon_1.png")); // 30x25
    23. SoundEffects::canonBallShot(1);
    24. game->scene->addItem(this);
    25.  
    26. // bullet cords
    27. moveByY = 1.0;
    28. moveDown = false;
    29. splashLasting = 0;
    30.  
    31. // shrani direction katero player trenutno is facing // saves the direction which the player is currently facing
    32. // (left==3, right ==1)
    33. direction = game->player->getLeftOrRightDirection();
    34. if(direction == 1){
    35. xPl = game->player->x()+83;
    36. yPl = game->player->y()+42;
    37. newX = game->player->x()+83;
    38. }else if(direction == 3){
    39. xPl = game->player->x()-18;
    40. yPl = game->player->y()+42;
    41. newX = game->player->x()-18;
    42. }
    43.  
    44. time = new QTimer();
    45. connect(time,SIGNAL(timeout()),this,SLOT(moveCanonBall()));
    46. time->start(5);
    47. }
    48.  
    49. Canon::~Canon(){
    50. delete time;
    51. }
    52.  
    53. bool Canon::getCanonBallGone(){
    54. return CanonBallGone;
    55. }
    56.  
    57. bool Canon::setCanonBallGoneToFalse(){
    58. CanonBallGone = false;
    59. }
    60.  
    61. bool Canon::setCanonBallGoneToTrue(){
    62. CanonBallGone = true;
    63. }
    64.  
    65.  
    66. void Canon::moveCanonBall(){
    67.  
    68. if(direction==1 && ballHitEnd==false){
    69. // s pomocjo balisticne enacbe zracunamo y // with a help of this function we calculate y ( parabolic movement of the canon ball )
    70. help = (0.5*(x()-xPl)*tan(0.6)-(0.5 *pow((x()-xPl),2))
    71. / (2*pow(20,2)*pow(cos(0.6),2))+yPl)-yPl;
    72. moveByY = yPl - help;
    73. setY(moveByY);
    74. setPos(x(),y());
    75.  
    76. // povecujemo x za 1.5 // incrementing x by 1.5
    77. setX(x()+1.5);
    78.  
    79. // ce je canon ball v vodi spremenimo sliko v splash sliko // if canon ball hits its final destination we change picture to a splash
    80. if(y() >= yPl+32){
    81.  
    82. ballHitEnd = true;
    83. setPixmap(QPixmap(":/Images/Splash_1.png"));
    84. }
    85.  
    86. }
    87.  
    88.  
    89. else if(direction==3 && ballHitEnd == false){
    90.  
    91. help = (0.5*(newX-xPl)*tan(0.6)-(0.5 *pow((newX-xPl),2))
    92. / (2*pow(20,2)*pow(cos(0.6),2))+yPl)-yPl;
    93. moveByY = yPl - help;
    94. setY(moveByY);
    95. setPos(x(),y());
    96.  
    97. // povecujemo x za 1.5 // incrementing x by 1.5
    98. newX = newX + 1.5;
    99. setX(x()-1.5);
    100.  
    101. // ce je canon ball v vodi spremenimo sliko v splash sliko // if canon ball hits its final destination we change picture to a splash
    102. if(y() >= yPl+32){
    103.  
    104. ballHitEnd = true;
    105. setPixmap(QPixmap(":/Images/Splash_2.png"));
    106. }
    107. }
    108.  
    109.  
    110.  
    111. // slika ostane nekaj sekund nato se canon sporsti s pomnilnika // picture stays as a splash for couple of microseconds then we delete the canon ball from memory
    112. if(ballHitEnd == true){
    113.  
    114. splashLasting++;
    115.  
    116. if(splashLasting == 15){
    117. game->scene->removeItem(this);
    118. CanonBallGone=true;
    119. delete this;
    120. }
    121. }
    122. // ce je canon ball sou izven scene ga sporstimo iz pomnilnika // if canon ball is out of the scene we remove it from the scene and delete it
    123. if(x()<(0-30) || x()>game->getW()+30){
    124. qDebug() << "deleted canonball";
    125. game->scene->removeItem(this);
    126. delete time;
    127. CanonBallGone=true;
    128. delete this;
    129. }
    130. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by MongKong; 27th March 2019 at 16:23.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,236
    Thanks
    303
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Program crashes when Canon ball reaches "water"

    In line 126 of canon.cpp, you delete "time", and in line 128 you delete "this". The destructor for Canon also deletes "time", so you are deleting it twice so that is probably what causes the crash. It could also be caused by the cannonball exploding when it hits the water.

    In any case, you should never delete an object instance while you are still executing methods for that instance. That isn't a good design in any case, but here since Canon is derived from QObject, you could replace calls to "delete this" with a call to "this->deleteLater()", which schedules the instance for safe deletion once control returns to the event loop.

    I have no idea why you make "CanonBallGone" a static member of the Canon class. By making it static, there is only one class-wide instance of this Boolean, and it applies to ALL cannonballs in the scene.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. The following user says thank you to d_stranz for this useful post:

    MongKong (27th March 2019)

  4. #3
    Join Date
    Mar 2019
    Posts
    22
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Program crashes when Canon ball reaches "water"

    Oh damn...i must've forgotten about the destructor.... I had the same problem in a Bullet class aswell and this seemed to fix it aswell !!!
    Thanks for the advice and about the static member, yeah i put it in there because i wanted my ship to fire a canon ball when CanonBallGone == true; that means player can only shoot one canon ball at once, he can make the next shot after the first canon ball has been deleted ( when it lands in water )
    Thank you very much, everything is working great now !!!

  5. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,236
    Thanks
    303
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Program crashes when Canon ball reaches "water"

    that means player can only shoot one canon ball at once, he can make the next shot after the first canon ball has been deleted
    There are better ways to do this. For example, all classes based on QObject have a QObject::destroyed() signal that is emitted in the QObject destructor. You can use this signal to detect when your cannonball is being destroyed instead of relying of a static (global) variable:

    Qt Code:
    1. void Ship::fireCannonball()
    2. {
    3. if ( canFireCannon() )
    4. {
    5. Canon * cannonball = new Canon( this );
    6. connect( canonball, &QObject::destroyed, this, &Ship::onCannonballDestroyed );
    7. cannonballInFlight = true;
    8. }
    9. }
    10.  
    11. void Ship::onCannonballDestroyed( QObject * ) // ignore "obj" argument since we know it is a cannonball
    12. {
    13. cannonballInFlight = false; // allows a new ball to be fired now
    14. }
    15.  
    16. bool Ship::canFireCannon()
    17. {
    18. return ( cannonballInFlight == false ); // cannonballInFlight is a member variable of Ship, initialized to false
    19. }
    To copy to clipboard, switch view to plain text mode 

    By making cannonballInFlight a member of Ship (instead of a global variable in Canon), you can have any number of ships firing cannonballs at the same time. Each Ship only has to check that it is allowed to fire another cannonball before it fires again. The last cannonball that it fired tells it when it is gone using the destroyed() signal, so the ship doesn't really have to do anything except wait for that after the cannonball is fired.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  6. The following user says thank you to d_stranz for this useful post:

    MongKong (28th March 2019)

  7. #5
    Join Date
    Mar 2019
    Posts
    22
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Program crashes when Canon ball reaches "water"

    Oh wow, that looks much better and easier to do, thank you !! Tho may i just ask, What is the point of having & operator at the beginning of QObject::destroyed and Ship:: onCannonBallDestroyed ? And why do you have to call onCannonballDestroyed using scope, if the method is part of the class Ship?

  8. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,236
    Thanks
    303
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Program crashes when Canon ball reaches "water"

    What is the point of having & operator at the beginning of QObject:: destroyed and Ship:: onCannonBallDestroyed
    Qt Code:
    1. connect( canonball, &QObject::destroyed, this, &Ship::onCannonballDestroyed );
    To copy to clipboard, switch view to plain text mode 

    This is the new, type-safe form of QObject::connect(), which uses the "pointer to member function" style of giving the signal and slot pair. "&QObject:: destroyed" is the address of (pointer to) the "destroyed" signal (a member function) of the QObject class.

    It is better to use this new style instead of the old one:

    Qt Code:
    1. connect( cannonball, SIGNAL( destroyed( QObject * ), this, SLOT( onCannonballDestroyed( QObject * ) ) );
    To copy to clipboard, switch view to plain text mode 

    because the new style will not compile if you give the wrong arguments. The old style will compile, but will fail at run time if you give it the wrong arguments. That isn't so good, because unless you read the messages coming from the runtime output in the debugger, you will not know that the connect() failed and will wonder why your app isn't handling the signals in the way you think it should be.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  9. The following user says thank you to d_stranz for this useful post:

    MongKong (29th March 2019)

  10. #7
    Join Date
    Mar 2019
    Posts
    22
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Program crashes when Canon ball reaches "water"

    Oh i see, then i believe this works with timers aswell and timeout() method?

  11. #8
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Program crashes when Canon ball reaches "water"

    Just as added info: the life time of a QObject can also be tracked with a QPointer
    Qt Code:
    1. class Ship : public QObject
    2. {
    3. private:
    4. QPointer<Canon> m_cannonBall;
    5. };
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. void Ship::fireCannonball()
    2. {
    3. if ( canFireCannon() )
    4. {
    5. m_cannonBall = new Canon( this );
    6. }
    7. }
    8.  
    9. bool Ship::canFireCannon()
    10. {
    11. return m_cannonBall.isNull();
    12. }
    To copy to clipboard, switch view to plain text mode 

    I.e. a QPointer tracks the QObject it is holding and resets itself to nullptr if the object is deleted

    Cheers,
    _

  12. The following 2 users say thank you to anda_skoa for this useful post:

    d_stranz (29th March 2019), MongKong (29th March 2019)

  13. #9
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,236
    Thanks
    303
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Program crashes when Canon ball reaches "water"

    Thanks, anda_skoa. I've learned something new. QPointer<> is a bit more useful in this circumstance and leads to less code and overhead.

    As I understand the docs, QPointer<> does not do reference counting in the way that std:: shared_ptr<> does. Also unlike shared_ptr, QPointer is not responsible for the lifetime of its object pointer. This also implies that you could potentially have several QPointer instances wrapping the same QObject pointer, correct? Presumably all of them connect to the same QObject:: destroyed() signal, and would simply set their internal copy of the pointer to null.

    I will have to think of a good use case for this.

    Oh i see, then i believe this works with timers aswell and timeout() method?
    Qt Code:
    1. connect( myTimer, &QTimer::timeout, this, &ThisClass::onTimeout );
    To copy to clipboard, switch view to plain text mode 

    (Of course, substitute the real name of your class for "ThisClass")

    Qt Code:
    1. connect( myTimer, &QTimer::timeout, [=]() { cannonball->deleteLater(); } );
    To copy to clipboard, switch view to plain text mode 

    Works with lambdas, too.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  14. The following user says thank you to d_stranz for this useful post:

    MongKong (29th March 2019)

  15. #10
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Program crashes when Canon ball reaches "water"

    Quote Originally Posted by d_stranz View Post
    Thanks, anda_skoa. I've learned something new.


    Quote Originally Posted by d_stranz View Post
    As I understand the docs, QPointer<> does not do reference counting in the way that std:: shared_ptr<> does.
    Also unlike shared_ptr, QPointer is not responsible for the lifetime of its object pointer.
    In terms of smart pointers you can think of QPointer as a weak-pointer, created from a shared-pointer inside the object itself.

    Quote Originally Posted by d_stranz View Post
    This also implies that you could potentially have several QPointer instances wrapping the same QObject pointer, correct?
    Yes, correct.

    Quote Originally Posted by d_stranz View Post
    Presumably all of them connect to the same QObject:: destroyed() signal, and would simply set their internal copy of the pointer to null.
    It is a bit more sophisticated than that

    Originally the implementation used some Qt internal functions to register the QPointer instances with the objects they were holding and the object would then notify the pointers as part of their destruction code.
    I.e. without going through the signal mechansim (as that would have required QPointer to be a QObject).

    The internals of the implementation changed and now literally uses a QWeakPointer for storing and monitoring.

    Quote Originally Posted by d_stranz View Post
    I will have to think of a good use case for this.
    Super useful in many circumstances.

    Cheers,
    _

  16. The following user says thank you to anda_skoa for this useful post:

    MongKong (29th March 2019)

  17. #11
    Join Date
    Mar 2019
    Posts
    22
    Thanks
    10
    Thanked 1 Time in 1 Post
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Program crashes when Canon ball reaches "water"

    d_stranz and anda_skoa thank you both for help and advices, i appreciate it a lot thank you again !!!!!

Similar Threads

  1. Replies: 1
    Last Post: 20th November 2015, 10:02
  2. Replies: 3
    Last Post: 16th March 2015, 07:31
  3. Replies: 1
    Last Post: 5th February 2011, 21:14
  4. "Cannot run program "C:\Qt\4.3.3\bin\qmake": file not found
    By PeteH in forum Installation and Deployment
    Replies: 1
    Last Post: 7th February 2009, 00:48
  5. Translation QFileDialog standart buttons ("Open"/"Save"/"Cancel")
    By victor.yacovlev in forum Qt Programming
    Replies: 4
    Last Post: 24th January 2008, 19:05

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.