Jump to content

  • Log In with Google      Sign In   
  • Create Account


Problem returning pointer from method


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
5 replies to this topic

#1 sooner123   Members   -  Reputation: 241

Like
0Likes
Like

Posted 07 December 2012 - 02:32 AM

I know this code is a mess and will have all types of NULL errors, but this is only the beginning and I haven't cleaned it up yet.

The only thing that I can't really figure out is why when the traverse method (which returns a pointer to a Location) is called, the program crashes.

I've tried putting in debug prints at various points in this method and so far have NOT gotten any consistent readout of the problem.

As I see it, it should initialize a sentinel pointer to ConnectionNode as the head of the list of Connections (a ConnectionNode) of the current Location, then traverse the list as long as the shortcut for the sentinel's current Connection is not equal to inputChar. Then when it finds a match it should return the Location pointer in the Connection for which the shortcut matched.

#include <iostream>
#include <string>
using namespace std;
class Location;
class Connection{
public:
  string direction;
  char shortcut;
  string description;
  Location* connectionDestination;
  Connection(string constructorDirection, char constructorShortcut, string constructorDescription){
   direction = constructorDirection;
   shortcut = constructorShortcut;
   description = constructorDescription;
   connectionDestination = NULL;
  }
};
struct ConnectionNode{
ConnectionNode* next;
Connection* data;
};
class Location{
public:
  string name;
  string description;
  ConnectionNode* connectionListHead;
  Location(string constructorName, string constructorDescription){
   name = constructorName;
   description = constructorDescription;
   connectionListHead = NULL;
  }
  void AddConnection(Connection* connectionToAdd){
   ConnectionNode*elem = new ConnectionNode;
   elem->data = connectionToAdd;
   //if the list of connections is currently NULL
   if (connectionListHead == NULL){
    elem->next = NULL;
    connectionListHead = elem;
   }
   //add new connection to end of list
   else{
    elem->next = connectionListHead;
    connectionListHead = elem;
   }
  }
  Location*traverse(char inputChar){
   ConnectionNode*elem = connectionListHead;
   while(elem->data->shortcut != inputChar){
    elem = elem->next;
   }
   return elem->data->connectionDestination;
  }
};

int main(){
//create our world
Location*roomC1 = new Location("Empty corridor",
  "You are in a dimly lit corridor with\npassageways to the north and west.");
Connection*linkC1toB1 = new Connection("West", 'w', "Passageway to the west");
roomC1->AddConnection(linkC1toB1);
Connection*linkC1toC2 = new Connection("North", 'n', "Passageway to the north");
roomC1->AddConnection(linkC1toC2);
//initialize game state variables
bool quit = 0;
char inputChar;
Location*currentRoom = roomC1;
ConnectionNode*currentConnection = NULL;

//main loop
while (!quit){
  //display current room information
  cout << endl << currentRoom->name << endl;
  for (int i=0; i<currentRoom->name.length(); i++) cout << "-";
  cout << endl << currentRoom->description << endl << endl;
  currentConnection = currentRoom->connectionListHead;
  //list all the connections to currentRoom
  while (currentConnection != NULL){
   cout << "-> " << currentConnection->data->direction
    << " [" << currentConnection->data->shortcut << "]"
    << " - " << currentConnection->data->description << endl;
   currentConnection = currentConnection->next;
  }
  cout << "-> Quit [q] - Exit game (progress will be lost)" << endl;
  cin >> inputChar;
  //set currentRoom equal to a pointer to the room whose connectionNode in the
  //current room has shortcut == inputChar
  if (inputChar == 'q') quit = 1;
  else{
   currentRoom = currentRoom->traverse(inputChar);
  }
}
}


Sponsor:

#2 Álvaro   Crossbones+   -  Reputation: 13002

Like
1Likes
Like

Posted 07 December 2012 - 02:52 AM

There is nothing setting connectionDestination to anything other than NULL in that code. So the traverse method returns NULL, so currentRoom becomes NULL and your program crashes.

#3 sooner123   Members   -  Reputation: 241

Like
0Likes
Like

Posted 07 December 2012 - 03:05 AM

Thanks. That fixed it

#4 Álvaro   Crossbones+   -  Reputation: 13002

Like
1Likes
Like

Posted 07 December 2012 - 03:27 AM

Here's a modified version of your code that is closer to how I would have written it, in case it helps you. I chose to identify locations by name, and I made the world a map from name to location. If you were thinking of having multiple locations with identical names, you may want to add the name back into the location and use a `code' instead as the identifier.

#include <iostream>
#include <string>
#include <vector>
#include <map>

struct Connection {
  std::string direction;
  char shortcut;
  std::string description;
  std::string destination;

  Connection(std::string direction, char shortcut, std::string description, std::string destination)
	: direction(direction),
	  shortcut(shortcut),
	  description(description),
	  destination(destination) {
  }
};

struct Location {
  std::string description;
  std::vector<Connection> connections;

  Location(std::string description = "")
	: description(description) {
  }
};

int main(){
  // Create our world (FIXME: This should come from a file)
  std::map<std::string, Location> world;
  world["Empty corridor"] = Location("You are in a dimly lit corridor with passageways to the north and west.");
  world["Empty corridor"].connections.push_back(Connection("West", 'w', "Passageway to the West", "West room"));
  world["Empty corridor"].connections.push_back(Connection("North", 'n', "Passageway to the North", "North room"));
  world["West room"] = Location("This is the room to the West of the corridor."); // Not feeling creative <img src='http://public.gamedev.net//public/style_emoticons/<#EMO_DIR#>/smile.png' class='bbc_emoticon' alt=':)' />
  world["West room"].connections.push_back(Connection("East", 'e', "Back to the corridor", "Empty corridor"));
  world["North room"] = Location("This is the room to the North of the corridor.");
  world["North room"].connections.push_back(Connection("South", 's', "Back to the corridor", "Empty corridor"));

  // Initialize game state variables
  std::string current_location_name("Empty corridor");

  // Main loop
  for (;;) {
	Location const &current_location = world[current_location_name];
  
	// Display current location information
	std::cout << current_location_name << '\n';
	for (int i=0, end=current_location_name.length(); i!=end; ++i)
	  std::cout << '-';
	std::cout << '\n';
	std::cout << current_location.description << "\n\n";
  
	// List all the connections to current_location
	for (int i=0, end=current_location.connections.size(); i!=end; ++i) {
	  Connection const &connection = current_location.connections[i];
	  std::cout << "-> " << connection.direction
				<< " [" << connection.shortcut << "]"
				<< " - " << connection.description << '\n';
	}
	std::cout << "-> Quit [q] - Exit game (progress will be lost)" << std::endl;
  
	// Get and process input. NOTE: Move this to a function to make code more clear, and to appease goto haters. <img src='http://public.gamedev.net//public/style_emoticons/<#EMO_DIR#>/smile.png' class='bbc_emoticon' alt=':)' />
	while (1) {
	  std::string input;
	  if (!std::getline(std::cin, input))
		goto QUIT;
	
	  char input_char = input[0];
	
	  if (input_char == 'q')
		goto QUIT;
	
	  // Find the connection whose shortcur matches input_char and move there
	  for (int i=0, end=current_location.connections.size(); i!=end; ++i) {
		Connection const &connection = current_location.connections[i];
		if (connection.shortcut == input_char) {
		  current_location_name = connection.destination;
		  goto CONNECTION_FOUND;
		}
	  }
	  std::cout << "Unrecognized input!\n";
	  std::cin.clear();
	}
  
  CONNECTION_FOUND:;
  }
QUIT:;
}

Edited by Álvaro, 07 December 2012 - 03:28 AM.


#5 brx   Members   -  Reputation: 713

Like
1Likes
Like

Posted 07 December 2012 - 03:40 AM

To be honest, I didn't dive too deep into the code, but the problem is that the connectionDestination of the Connection is never initialized (except for the NULL initialization in the Connection constructor). So at the end of the traverse method it will always return a NULL pointer, so currentRoom is NULL after calling traverse.

[EDIT] Damn... forgot to refresh. I opened the topic about two hours ago but then was away from the computer for a while...

Edited by brx, 07 December 2012 - 03:41 AM.


#6 sooner123   Members   -  Reputation: 241

Like
0Likes
Like

Posted 08 December 2012 - 07:04 PM

But thank you for taking the time, brx.

And thanks a ton for the code rewrite Alvaro. I'll be pouring over it and doubtless learning a lot.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS