Thread: Program crashes at very end

  1. #1
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92

    Program crashes at very end

    Hello all ... could you please look over this code, critique it and let me know why it crashes at the end?

    TIA!

    main.cpp
    Code:
    #include <iostream>
    #include <string>
    #include "World.h"
    #include "Player.h"
    
    using namespace std;
    
    int main(){
    
      World world;
    
      cout << "World Name = " << world.getName() << endl;
    
      char* pName;
    
      cout << "What is your name?" << endl;
    
      cin >> pName;
    
      Player player;
    
      player.setName(pName);
    
      cout << player.getName() << endl;
    
      return 0;
    }
    player.h
    Code:
    #ifndef PLAYER_H
    #define PLAYER_H
      class Player {
        public:
    
          char* getName();
          void setName(char* _pstrPlayerName);
    
        protected:
    
          char* _pstrPlayerName;
    
      };
    #endif
    player.cpp
    Code:
    #include <string>
    #include "Player.h"
    
    void Player::setName(char* playerName){
    
      _pstrPlayerName = playerName;
    
    }
    
    char* Player::getName(){
    
      return _pstrPlayerName;
    
    }
    world.h
    Code:
    #ifndef WORLD_H
    #define WORLD_H
    
    class World {
    
      public:
    
        World();
        char* getName();
    
      protected:
    
        char* _pstrWorldName;
    
    };
    
    #endif
    world.cpp
    Code:
    #include "World.h"
    
    World::World(){
    
      _pstrWorldName = "Something";
    
    }
    
    char* World::getName(){
    
      return _pstrWorldName;
    
    }
    Output:
    Code:
    World Name = Something
    What is your name?
    Stuff
    
    Process returned -1073741819 (0xC0000005)   execution time : 14.163 s
    Press any key to continue.
    If I comment out the two lines referring to World, it runs with no errors.

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    A pointer is really just a glorified integer. It holds the address of some piece of data. Before you set it to some value, you need to consider the lifetime and ownership of the object it is pointing to, and above all it must be pointing somewhere valid at all times (in this context NULL is valid).

    >> char* pName;

    This variable points to nowhere in particular. Assign it to some chunk of memory.

    >> _pstrPlayerName = playerName;

    What is the lifetime of the object that was passed to the function, and who owns it? Make a copy.
    Last edited by Sebastiani; 07-22-2009 at 12:54 AM. Reason: wording
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92
    I created a NULL pointer out of pName and changed the assignment line to

    Code:
    void Player::setName(char* playerName){
    
      strcpy(_pstrPlayerName, playerName);
    
    }
    and it still crashes. :\

  4. #4
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> I created a NULL pointer out of pName and changes the assignment line to

    Ok, so now the variable hold the address starting at the 0th offset in ram. You send the variable to strcpy and it attempts to write some data there. The problem is, your program doesn't have any business with that address in memory! You need to allocate some yourself, either on the stack or on the heap.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  5. #5
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92
    Ok, I see what you're saying.

    Is there a way to dynamically expand the memory allocated to a char pointer to prevent a buffer over flow on:

    Code:
    char* pName = new char[10];

  6. #6
    Kiss the monkey. CodeMonkey's Avatar
    Join Date
    Sep 2001
    Posts
    937
    You can dynamically expand a block of data by allocating a bigger block and copying (then delete the old one). std::string does this for you.
    "If you tell the truth, you don't have to remember anything"
    -Mark Twain

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    This is roughly the minimum "standard" implementation you might have. Notice that it is *extremely* important that you define a copy constructor and operator= if you have a class containing pointers (which is one reason why they should be avoided at all costs!):

    Code:
      class Player {
        public:
          Player();
          Player(const Player& rhs);
          Player& operator =(const Player& rhs);
          char* getName() const;
          void setName(char* _pstrPlayerName);
          virtual ~Player();
        protected:
          void cleanup();
          char* _pstrPlayerName;
    
      };
    
    
    Player::Player() : _pstrPlayerName(NULL){
    
      setName("");
    
    }  
      
    Player::Player(const Player& rhs) : _pstrPlayerName(NULL){
    
      *this = rhs;
    
    }  
      
    Player& Player::operator =(const Player& rhs){
    
      setName(rhs.getName());
      return *this;
    
    }  
      
    void Player::setName(char* playerName){
    
      cleanup();
      _pstrPlayerName = new char[strlen(playerName) + 1];
      strcpy(_pstrPlayerName, playerName);
    
    }
    
    char* Player::getName() const {
    
      return _pstrPlayerName;
    
    }
    
    void Player::cleanup(){
    
      delete [] _pstrPlayerName;
      _pstrPlayerName = NULL;
    
    }
    
    Player::~Player(){
    
      cleanup();
    
    }
    Of course this would be much more simple using an std::string. Notice how the minimum standard for non-pointer containing classes is much less stringent:

    Code:
      class Player {
        public:
          string getName() const;
          void setName(const string& _pstrPlayerName);
        protected:
          string _pstrPlayerName;
    
      };
    
    void Player::setName(const string& playerName){
    
      _pstrPlayerName = playerName;
    
    }
    
    string Player::getName() const {
    
      return _pstrPlayerName;
    
    }
    Big difference, no?
    Last edited by Sebastiani; 07-22-2009 at 01:31 AM. Reason: added setName("")
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #8
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92
    Quote Originally Posted by Sebastiani View Post
    Big difference, no?
    Just a little bit.

  9. #9
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92
    Ok, I got it working with no errors with:

    Code:
    #ifndef PLAYER_H
    #define PLAYER_H
      class Player {
        public:
    
          const std::string getName();
          void setName(const std::string& _strPlayerName);
    
        protected:
    
          std::string _strPlayerName;
    
      };
    #endif
    Code:
    #include <string>
    #include "Player.h"
    
    void Player::setName(const std::string& playerName){
    
      _strPlayerName = playerName;
    
    }
    
    const std::string Player::getName(){
    
      return _strPlayerName;
    
    }
    Code:
    #include <iostream>
    #include <string>
    #include "World.h"
    #include "Player.h"
    
    using namespace std;
    
    int main(){
    
      World world;
    
      cout << "World Name = " << world.getName() << endl;
    
      string pName = "";
    
      cout << "What is your name?" << endl;
    
      cin >> pName;
    
      Player player;
    
      player.setName(pName);
    
      cout << player.getName() << endl;
    
      return 0;
    }
    I had to put std:: in front of each string. Thanks for your help!

  10. #10
    Registered User Cooloorful's Avatar
    Join Date
    Feb 2009
    Posts
    59
    Just for future reference...

    Code:
      class Player {
       typedef std:string string; 
       public:
    
          const string getName();
          void setName(const string& _strPlayerName);
    
        protected:
    
          string _strPlayerName;
    
      };
    ... also works without changing your code too terribly.

  11. #11
    Registered User Kudose's Avatar
    Join Date
    Jun 2006
    Posts
    92
    I think you meant typedef std::string string ?

  12. #12
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    .. also works without changing your code too terribly.
    No, that gives you a compile error. I think you meant:
    Code:
    typedef std::string string
    That is a bad idea though because if you ever add something like
    Code:
    using namespace std;
    you will now get another compile error.

    The best way to avoid explicitly adding std:: before each string declaration would be to do:
    Code:
    using std::string;
    class Player {
       public:
          const string getName();
          void setName(const string& _strPlayerName);
        protected:
          string _strPlayerName;
      };

  13. #13
    Registered User Cooloorful's Avatar
    Join Date
    Feb 2009
    Posts
    59
    Code:
    using std::string;
    class Player {
       public:
          const string getName();
          void setName(const string& _strPlayerName);
        protected:
          string _strPlayerName;
      };
    Is ok on a small project. If you are building something larger I would urge you to utilize namespaces.

    Code:
    namespace UI
    {
      using std::string;
      class Player;
    }
    Which prevents ambiguity across your entire program.

  14. #14
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    And if you want to get really fancy about it you could employ something like this:

    Code:
    struct default_player_traits
    {
    	typedef std::string
    		string_type;
    	// ...etc...
    };
    
    template < typename Traits = default_player_traits >
    class BasicPlayer
    {
    	public:
    	
    	typedef typename Traits::string_type
    		string;
    	// ...etc...
    };
    
    typedef BasicPlayer< >
    	Player;
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  15. #15
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Traits too? You really do love template solutions, don't you?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Adventures in labyrinth generation.
    By guesst in forum Game Programming
    Replies: 8
    Last Post: 10-12-2008, 01:30 PM
  2. Calling delete Crashes my Program
    By thetinman in forum C++ Programming
    Replies: 19
    Last Post: 10-13-2007, 03:07 AM
  3. Program Crashes when i modify one of the parameters
    By pinkcheese in forum C++ Programming
    Replies: 2
    Last Post: 01-28-2003, 08:46 AM
  4. program crashes
    By Strut in forum Linux Programming
    Replies: 3
    Last Post: 02-10-2002, 10:49 AM
  5. My program crashes with this code
    By blackwyvern in forum C++ Programming
    Replies: 3
    Last Post: 01-28-2002, 12:28 AM