0

I am implementing a path planning algorithm using graphs. In my implementation I have structures Node and Edge. One of the members of Node is a list of edges. I have a weird problem that came up in my code when I used a pointer to a node in an array, I've managed to isolate it below:

int main()
{
  // Node node_array[5];                            // If I use this array, the program works fine.
  Node* node_array=(Node*)calloc(5, sizeof(Node) ); // This causes a problem

  Node* pointer_to_node=&(node_array[0]); 
  pointer_to_node->id=0;

  cout << "Did it work?" << "\n";//.
  cout << pointer_to_node->id << "\n";     // This works fine
  cout << (*pointer_to_node).id << "\n";   // This works fine
  Node bla=*pointer_to_node;               //This crashes the program. But if I remove the list of edges from Node, then it works fine.
  cout << "Yes it worked!" << "\n";        // Something is breaking if I don't reach this.
}

The program crashes (exists without printing "Yes it worked!") when I try to dereference pointer_to_node. There are three things I've noticed.

-If I define a Node, form a pointer and then dereference it, there is no problem.

-If I create an array of nodes using Node node_array[5];, the program works fine.

-If I remove the list of edges member from Node, everything works fine.

I know there are probably many easier ways to implement something like this, but I'm curious to know what exactly am I breaking here to make the program crash. I'm new to c++ and Stack Overflow, so any feedback is appreciated.

Here is the rest of the code above main()

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <time.h>
#include <sys/time.h>
#include <math.h>
#include <iostream>
#include <list>
using namespace std;

struct Node;        // NOTE: we'll define this in detail later, but we need it now
struct Edge;

// this is a basic graph node
struct Node
{
  int id;
  list<Edge> edges; // these are edges from {nodes which this node can be accessed}
};

//basic edge data stucture
struct Edge
{
  Node* startNode;     // the edge starts at this node
  Node* endNode;       // the edge goes to this node
  double edgeCost;     // going along the edge cost this much
};

  • 1
    Don't use `malloc`, `calloc`, or `realloc` in C++. Get [a good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – molbdnilo Apr 09 '19 at 13:17

1 Answers1

3

Your Node contains a list. This is a C++ class with its own non-trivial state. The difference between Node node_array[5]; and calloc(5, sizeof(Node) ) is that the first one will actually call the constructors properly. The code bombs when trying to copy this badly initialized list somewhere else. If you want a dynamic allocation, use new Node[5] instead.

P.W
  • 26,289
  • 6
  • 39
  • 76