C++ Tree Data Structure - c++

Background:
So I've been porting some of my older Java code to C++, and I've come across an issue that's making proceeding quite difficult. My project uses a tree data-structure to represent the node hierarchy for 3D animation.
Java:
public final class Node {
private final Node mParent;
private final ArrayList<Node> mChildren;
//private other data, add/remove children / parents, etc ...
}
In Java, its quite simple to create a tree that allows for modification etc.
Problem:
I'm running into issues is with C++, arrays cannot easily be added to without manually allocating a new chunk of memory and having the existing ones moved over so I switched to std::vector. Vectors have the issue of doing what I just described internally making any pointers to there elements invalid. So basically if you wan't to use pointers you need a way to back them so memory holding the actual nodes doesn't move. I herd you can use std::shared_ptr/std::unique_ptr to wrap the nodes in the std::vector, and I tried to play around with that approach but it becomes quite unwieldy. Another option would be to have a "tree" class that wraps the node class and is the interface to manipulate it, but than (for my use case) it would be quite annoying to deal with cutting branches off and making them into there own trees and possibly attaching different branches.
Most examples I see online are Binary trees that have 2 nodes rather than being dynamic, or they have many comments about memory leaks / etc. I'm hoping there's a good C++ alternative to the java code shown above (without memory leak issues etc). Also I won't be doing ANY sorting, the purpose of the tree is to maintain the hierarchy not to sort it.
Honestly I'm really unsure of what direction to go, I've spent the last 2 days trying different approaches but none of them "feel" right, and are usually really awkward to manage, any help would be appreciated!
Edit:
An edit as to why shared_ptrs are unwieldy:
class tree : std::enable_shared_from_this<tree> {
std::shared_ptr<tree> parent;
std::vector<std::shared_ptr<tree>> children;
public:
void set_parent(tree& _tree) {
auto this_shared_ptr = shared_from_this();
if (parent != nullptr) {
auto vec = parent->children;
auto begin = vec.begin();
auto end = vec.end();
auto index = std::distance(begin, std::find_if(begin, end, [&](std::shared_ptr<tree> const& current) -> bool {
return *current == this_shared_ptr;
}));
vec.erase(std::remove(begin, end, index), end);
}
parent = std::shared_ptr<tree>(&_tree);
if (parent != nullptr) {
parent->children.push_back(this_shared_ptr);
}
}
};
working with pointers like above becomes really quite verbose, and I was hoping for a more simple solution.

You could store your nodes in a single vector and use relative pointers that are not changed when the vectors are resized:
typedef int32_t Offset;
struct Node {
Node(Offset p) : parent(p) {}
Offset parent = 0; // 0 means no parent, so root node
std::vector<Offset> children;
};
std::vector<Node> tree;
std::vector<uint32_t> free_list;
To add a node:
uint32_t index;
if (free_list.empty()) {
index = tree.size();
tree.emplace_back(parent_index - tree.size());
} else {
index = free_list.back();
free_list.pop_back();
tree[index].parent = parent_index - index;
}
tree[parent_index].children.push_back(index - parent_index);
To remove a node:
assert(node.children.empty());
if (node.parent) {
Node* parent = &node + node.parent;
auto victim = find(parent->children.begin(), parent->children.end(), -node.parent);
swap(*victim, parent->children.back()); // more efficient than erase from middle
parent->children.pop_back();
}
free_list.push_back(&node - tree.data());

The only reason for the difference you're seeing is if you put the objects directly in the vector itself in c++ (which you cannot do in Java.) Then their addresses are bound to the current allocated buffer in the vector. The difference is in Java, all the objects themselves are allocated, so only an "object reference" is actually in the array. The equivalent in c++ would be to make a vector of pointers (hopefully wrapped in smart pointer objects) so the vector elements only are an address, but the objects live in fixed memory. It adds an extra pointer hop, but then would behave more like what you expect in java.
struct X {
char buf[30];
};
std::vector<X> myVec{ X() };
Given the above, the X elements in myVec are contiguous, in the allocation. sizeof(myVec[0]) == sizeof(X). But if you put pointers in the vector:
std::vector<unique_ptr<X>> myVec2{ make_unique<X>() };
This should behave more like what you want, and the pointers will not become invalid when the vector resizes. The pointers will merely be copied.
Another way you could do this would be to change things a little in your design. Consider an alternate to pointers entirely, where your tree contains a vector of elements, and your nodes contain vectors of integers, which are the index into that vector.

vector, forward_list, ..., any std container class (other than built-in array or std::array) may be used.
Your trouble seems to be that java classes are refrence types, while C++ classes are value types. The snippet below triggers "infinite recursion" or "use of incomplete type" error at compiletime:
class node{
node mParent;//trouble
std::vector<node> children;
//...
};
the mParent member must be a reference type. In order to impose reference semantics you can make it a raw pointer:
node* mParent;
you may also use pointer as the argument type to the container, but as a C++ beginer that would most probably lead to memory leaks and wierd runtime errors. we should try to stay away from manual memory management for now. So the I modify your snippet to:
class node{
private:
node* const mParent;
std::vector<node> children;
public:
//node(node const&)=delete;//do you need copies of nodes? you have to properly define this if yes.
node(node *parent):
mParent{parent}{};
void addChild(/*???*/){
children.emplace_back(this);
//...
};
//...
};

Related

What's the purpose of the extra std::list that boost::heap::d_ary_heap holds when configured for mutability?

When configured for mutability, boost::heap::d_ary_heap uses a std::list in addition to the vector that holds the values of the heap nodes. I realize that the handles which are being provided for making the mutable_heap_interface work are in fact iterators of this list, but I'm wondering why such an expensive solution was chosen, and if there's a leaner way to achieve mutability with boost::heap::d_ary_heap.
Mutability requires a way to find the index of a node in the heap vector, given the node itself. Some kind of backward pointer needs to be maintained. Can't this be achieved by storing this backwards pointer in the node, and maintain it by the move/copy constructors/assignment-operators of the value type?
Is there a good reason why it needs to be as expensive as a doubly-linked list?
This is kind of an answer to my own question that only speculates why the boost design is as it is, and presents a partial solution to what I would have liked to get with the boost data structure. I'm still interested in receiving further insight into the rationale behind the boost implementation, and of course also feedback on the solution I present below.
Let me first explain the piece of code below, before going on to discuss its merits and problems, and then comment on the boost.heap implementation, why it presumably is like it is, and why I don't like it.
The code below is based on the venerable std::priority_queue. It splits the node managed by the priority queue into a handle and a body. The handle goes into the heap at the core of the priority_queue, and therefore moves around in the underlying vector as entries are added or removed. The handle only contains the priority value and a pointer to the body, in order to make it cheap to move it around. The body is a potentially large object that remains stationary in memory. It holds a backpointer to the handle, because the handle must be invalidated when the body's priority changes, or the body disappears.
Since the handle moves around in the heap, the backpointer in the body must be updated each time the handle changes location. This is done in the move constructor and the move assignment operator of the handle. If a handle gets invalidated, both the pointer in it and the backpointer pointing at it are nulled.
#include <queue>
//! Priority queue that works with handles to managed objects.
template<typename Prio, typename Object> struct PriorityQueue {
struct Entry;
//! Each heap entry is a handle, consisting of a pointer to the managed object and a priority value.
struct Entry {
Object *obj_;
Prio val_;
Entry(Entry const &) =delete;
Entry &operator=(Entry const &) =delete;
~Entry() {
if(obj_)
obj_->setLink(nullptr);
}
Entry(Object &obj, Prio val)
: obj_{&obj}
, val_{val}
{
if(obj_)
obj_->setLink(this);
}
Entry(Entry &&v)
: obj_{v.obj_}
, val_{v.val_}
{
if(obj_)
obj_->setLink(this);
v.obj_ = nullptr;
}
Entry &operator=(Entry &&v) {
if(&v != this) {
val_ = v.val_;
if(obj_)
obj_->setLink(nullptr);
obj_ = v.obj_;
if(obj_)
obj_->setLink(this);
v.obj_ = nullptr;
}
return *this;
}
friend bool operator<(Entry const &a, Entry const &b) {
return a.val_ < b.val_;
}
};
Prio add(Object &obj, Prio val) {
while(!heap_.empty() && !heap_.top().obj_)
heap_.pop();
heap_.emplace(obj, val);
return heap_.top().val_;
}
Prio remove(Object &obj) {
// We can't remove the entry straight away, so we null the pointer
// and leave the entry in the heap, where it will eventually bubble
// up to the root position, from where it can be removed.
if(obj.getLink()) {
obj.getLink()->obj_ = nullptr;
obj.setLink(nullptr);
}
while(!heap_.empty() && !heap_.top().obj_)
heap_.pop();
return heap_.empty() ? INT64_MAX : heap_.top().val_;
}
Prio update(Object &obj, Prio val) {
remove(obj);
return add(obj, val);
}
std::priority_queue<Entry> heap_;
};
//! Example of a managed object.
struct MyObject {
MyObject(MyObject const &) =delete;
MyObject &operator=(MyObject const &) =delete;
PriorityQueue<int, MyObject>::Entry *getLink() const {
return link_;
}
void setLink(PriorityQueue<int, MyObject>::Entry *link) {
link_ = link;
}
PriorityQueue<int, MyObject>::Entry *link_;
};
Unfortunately, std::priority_queue doesn't support mutability, i.e. you can't remove entries except the root entry, so the fallback is to leave handles in the heap, but invalidate them by breaking the relationship with the body. They will eventually bubble up towards the root, where they can be removed. Obviously, that means that they inflate the size of the heap needlessly, consuming some additional memory and CPU time, which may or may not be significant. If std::priority_queue would expose the internal heap maintenance functions, it would be possible to delete or update entries directly.
It would be possible to reduce the handle size even more by holding the priority in the body rather than the handle, but then the body would need to be consulted for each priority comparison, which would destroy locality of reference. The chosen approach avoids this by holding everything in the handle that is relevant for heap maintenance. The updating of the backpointer in the body by the move constructor and move assignment operator is a write-only operation, which needn't hinder performance, since there typically are write buffers in modern processors that can swallow the associated latency.
For optimizing cache performance, one would wish to use a d-ary heap instead of a binary heap, so that all children of a node (i.e. their handles), which are adjacent in the vector, occupy one cache line. Alas, that's not supported by std::priority_queue, either.
The latter would be supported by boost.heap, but in order to also support mutability, they introduce an additional std::list for the management of the backpointers, which I suspect is rooted in the age of the library. It dates back to before C++11, when move support wasn't yet available in the language. Presumably, only minimal maintenance has been done to it since. I'd welcome them bringing the library up to date and use the opportunity to provide leaner implementations.
So, the bottom line is that I have at least a suspicion that answers my original question, and a design that addresses some of my goals, leaving me with a workable but not yet optimal solution based on the standard library.
Thanks go to the commenters, and remember if you have additional insight to add, you're most welcome.

Copy constructor for a vector of pointers

I'm trying to create a node class that contains a vector of pointers. Here's my code:
node.h:
#ifndef NODE_H
#define NODE_H
class node
{
public:
vector<node*> next;
void add_arc(node & a)
string some_string;
#endif
node.cpp:
void node::add_arc(node & a)
{
node *b = &a;
next.push_back(b); //only copyies nodes
}
main.cpp:
int main()
{
vector<node> nodes;
node a;
node b;
node c;
a.somestring = "a";
b.somestring = "b";
c.somestring = "c";
a.add_arc(b); //a should point to b
a.add_arc(c); //a should point to c
nodes.push_back(a);
nodes.push_back(b);
nodes.push_back(c);
cout << nodes[0].next.size() << endl; // prints "2", works fine
cout << nodes[0].next[0]->some_string << endl; //empty
}
I thought it would be as easy as just overloading push_back:
void push_back(vertex * pointer)
{
next.push_back(pointer);
}
But I think I really need a copy constructor, or some other method to make this work. How would I go about doing this for a vector of pointers?
Edit: I guess I didn't explain it well. Look at the answers in this question:
Segmentation fault when accessing a pointer's member function in a vector
Making 'a' a reference did not work for me
It works...
Your code generates as expected the correct output (see online demo):
2
b
...However this design is not future proof
However this result is related somehow to luck, because in your code snippet:
the nodes in the nodes vector are copies of the original object including all their pointers
the local objects a, b, c to which these pointers point still exist
However in more complex code, you'd quickly end up with dangling pointers.
Imagine:
Bad example 1: you create a graph, keeping all the nodes directly in a vector of nodes. You then add the first arcs between the nodes. As soon as you'll add a new node to the vector, reallocation might occur and you'd risk to see all your next pointers invalidated.
Bad example 2: you initialise a graph like you did, but in a function called by main. In this case, as soon as you return from this function, all the local nodes get destroyed and the vector's node will point to objects that do no longer exist. UB guaranteed !
How to improve ?
Your design fails to recognize that the nodes all belong to the same graph.
There is a quick and dirty way out: always create the node from the free store, and store them in a vector<node*>.
vector<node*> nodes;
node *a = new node("a"); // Imagine a node constructor
node *b = new node("b");
a->add_arc(b); //change signature, to accept a pointer
nodes.push_back(a);
nodes.push_back(b);
There's a better approach: improve further the previous approach, but use shared_ptr<node*> to make sure that nodes that are no longer referenced (neither by a vector of nodes, nor by an arc) are destroyed automatically.
There's an even better approach: encapsulate the nodes in a class representing a graph. In this case, you could consider using a vector<nodes> and replace the pointers in next, by indexes of the target nodes in the vector. No pointer, but perfect copy of graphs will be much easier. And no more memory management hassle.
class node // just to give the general idea
{
public:
vector<int> next; // not usable without the graph
void add_arc(int a)
string id;
};
class graph {
vector<node> nodes;
public:
void add_node (node a);
void add_arc (string from, string to);
node& operator[] (size_t i);
...
};

C++ Branching recursive struct?

I have the following. The struct is prototyped so it compiles fine.
struct vertexNodeInfo
{
vector<vertexNodeInfo> node;
};
I'm trying to write an octree thingy. What I want to do is use a recursive function to continue adding a node to each node until I get down to a specific point, at which time the function, rather than adding another node, adds a leaf. I want to use no memory when there's no further node or leaf added if that's possible.
Maybe templates would help in this situation, but I'm not sure how to use them...
I don't think I've explained myself well. Here's a diagram:
I have no idea if what I'm asking for is impossible or too confusing to understand or just plain dumb, but I can't figure it out on my own. I'm sorry that I can't explain it any better.
I'm using C++98/03 (VC++2008) and cannot use C++11
Any help at all would be much appreciated.
ADDITIONAL INFO:
Better explanation: I want an array of an array of an array of an array of data. Memory usage is very important in this (I'm storing several million elements, so a single byte makes a huge difference). Each array can contain 8 more arrays, but until I need to use it I want each one of the arrays to use no memory. It's an octree of sorts.
MORE ADDITIONAL INFO:
Here's another diagram. It's a little big, so you might need to right click it and select Open image in new tab to make it readable.
What I don't want are "brown" (red+green) boxes, where every box reserves memory for both more nodes and for the leaf data. That would use far too much memory for my needs.
This is basically what I'm trying to achieve, pictured as 2D for simplicity:
Without any (manual) heap allocation[1]:
struct NodeInfo {
int id;
};
using Tree = boost::make_recursive_variant<
NodeInfo,
std::vector<boost::recursive_variant_>
>::type;
I know variants come with their own "complexity", but memory locality is preserved and manual memory management avoided.
Now to get closer to your stated optimization goals, you could use std::array<T, 8> instead of the std::vector, or perhaps just make the vector use a custom allocator to allocate from a memory pool.
Sample program (see it Live on Coliru):
#include <iostream>
#include <boost/variant.hpp>
#include <vector>
struct NodeInfo {
int id;
};
using Tree = boost::make_recursive_variant<
NodeInfo,
std::vector<boost::recursive_variant_>
>::type;
// for nicer code:
using Branch = std::vector<Tree>;
using Leaf = NodeInfo;
static std::ostream& operator<<(std::ostream& os, Leaf const& ni) {
return os << ni.id;
}
static std::ostream& operator<<(std::ostream& os, Branch const& b) {
os << "{ ";
for (auto& child: b) os << child << " ";
return os << "}";
}
int main()
{
Branch branch1 {
Leaf { 2 },
Leaf { 1 },
Branch {
Leaf { 42 },
Leaf { -42 },
}
};
Tree tree = Branch { branch1, Leaf { 0 }, branch1 };
std::cout << tree << "\n";
}
Prints:
{ { 2 1 { 42 -42 } } 0 { 2 1 { 42 -42 } } }
[1] (outside the use of std::vector)
The core structure of the octree is
struct Node {
std::vector<T> items;
std::array<std::unique_ptr<Node>, 8> subnodes;
Box BoundingBox;
};
class Octree {
Node n;
//... stuff
public:
Octree(Box location)
: n(location) {}
};
If you're desperate for a few extra bytes on the leaf nodes (and a few bytes lost on the non-leaf nodes), you can try using a pointer to the subnodes array rather than holding it by value.
Now, if T is a point, then you can get away with using a boost::variant to store only the items or the subnodes, because each point is guaranteed to exist in exactly one subnode, and you can pick an arbitrary cutoff point between having items and having subnodes.
Else if T is a kind of bounding-box, you cannot get away with this, because the bounding boxes that do not fit completely into any of the subnodes must go into the items list, so the items list must exist regardless of whether or not there are subnodes.
What I'm also going to say is that if you're desperate for either time or space optimizations, you should seriously look into custom memory allocation routines.
Edit: Yes, I used an array of pointers, rather than a pointer to an array. The long and short is that describing the correct initialization of that array without some strong C++11 support is a complete bitch and in my personal use, it didn't warrant the serious issues I had actually making the damn thing. You can try std::unique_ptr<std::array<Node>, 8> if you want. It should, in theory, be the superior choice.
What about polimorphism?
struct TreeElem {
virtual ~TreeElem() {}
};
struct Node : public TreeElem {
std::vector<TreeElem*> _children;
};
struct Leaf : public TreeElem {
int _value;
};
You can figure out the rest (virtual members of TreeElem).
P.S: if it's more than something trivial, use smart pointers.
Check che composite pattern and you can adapt it easily to perform an octree. After this, create the recursive function that take as argument the actual octree depth, so you can easyli perform what you want. Unfortunately, I don't understand well your question so I can't be more precise.

Good Node definition for ordered tree in C++

I have a rooted ordered tree representing sets of integers. Each node stores the size of the associated subtree, and also the max and min elements in this subtree. The branch degree of all the nodes if fixed (but determined at runtime). Also for sufficiently small subtrees I would like to change the representation to a bitmap for the subset associated. For example the root node may store a set of size 1000000, one of this children would store a subset of size 100000, then again one of his children would store a subset of size 10000 and in the next level we would stop using this representation and store just a plain bitmap for the associated subset.
I'm trying to implement this structure in C++ and my definition for the node type stores three integers (size, min and max), an array of pointers (something like node_t ** children) to subtrees and the bitmap (in case we are using this representation). The problem is that all the nodes are storing at least one element which is irrelevant (if the set is big enough we would be using the array of pointers but not the bitmap, for example). How should the node type be declared to solve this problem ? I thought about using two subtypes of node (one for each case) but I am not sure what the impact on the performance at runtime would be.
Thanks in advance.
PS. Please let me know if the question is unclear to edit it.
Since you're using multiple representations, you'll probably need at least two node types: The first will be a generic node that handles the root as well as nearby descendants, and the second type will contain a pointer to a map. The latter nodes don't have any children persay, but their immediate ancestors should see them as an entire sub-tree rather than a terminating node that points to a map.
Since each of the upper nodes have pointers to their children, you'll need a way to ensure that these pointers are also able to point to the mapNodes as well as the branching ones. A good way to do this is to create a virtual base node type with a virtual function that returns whatever data you're looking for. For example:
class baseNode {
virtual int getLargest();
virtual baseNode* addData(int);
};
class leafNode : baseNode { //for non-map termination
leafNode(int in) {Data = in;}
int getLargest() {return Data;}
baseNode* addData(int);
int Data;
};
class treeNode : baseNode {
public:
int getLargest(); //returns leftChild->getLargest(), etc
baseNode* addData(int);
baseNode* leftChild;//can point to either a treeNode or mapNode
baseNode* rightChild;
};
class mapNode : baseNode {
baseNode* addData(int);
int getLargest(); //parses subMap to find/return the desired value
Map* subMap;
};
You'll need a bit of finessing to get it to do what you need it to, but the principle is the same. Keep in mind that with 1m objects, every byte you add increases the net memory use by about a megabyte, so do try to keep things minimal. If all of your branching nodes eventually reach a mapNode, you can eliminate the leafNode declaration altogether.
Adding data to the structure is tricky, especially since you're working with multiple types and the parents (hopefully) don't know anything about their neighbors; Use virtual accessors to do what's needed. In many scenarios, if a branching node tries to add a value 'down the line', the child node it references may need to change type. In this case, the child should construct the new substructure then return it to the parent. This can be done like so:
baseNode* treeNode::addData(int in) {
if ((childCount+1) < threshold) { //not enough to merit a map
//....
//if (input needs to go to the leftChild) {
if (leftChild == 0) {
leftChild = new leafNode(in);
} else {
leftChild = leftChild->addData(in);
}
//}
return (baseNode*)this; //casting may be optional
} else { //new Data merits converting self + kids into a map
mapNode* newMap = new mapNode();
//Set newMap->subMap to children, deleting as you go
delete this;//remove self after return
return (baseNode*)newMap; //return the mapNode holding subtree
}
}
baseNode* leafNode::addData(int in) {
treeNode* tmpNode = new treeNode(); //create replacement
tmpNode->leftChild = this; //pin self to new node
tmpNode->rightChild = new leafNode(in); //store data
return (baseNode*)tmpNode;
}
baseNode* mapNode::addData(int in) {
subMap->addValue(in);//However you do it...
return (baseNode*)this; //parent is always a treeNode
}
The leftChild = leftChild->addData(in); usually won't actually modify anything, especially if it points to a treeNode, however it doesn't really hurt anything to do so and the extra if (newPtr != leftChild) check would just add unnecessary overhead. Note that it will cause a change if a leafNode needs to change into a treeNode with multiple kids, or if it's a treeNode with enough children to merit changing itself (and it's kids!) into a mapNode.

C++ adjacency list of pointers and structs

Working on adjacency list --> directed weighted graph
One class looks like this, i.e. header:
class CGraph;
class CMap {
public:
//voided constructors and destructors
//functions one is:
void SetDirGraph(string commands);
private:
CGraph* m_myMap;
};
Second class:
class CNode {
public:
//voided constructor and desctructor
int m_distance, m_vert;
bool m_isKnown;
};
typedef struct edges {
int v2, weight;
} edge;
class CGraph {
public:
CGraph(int map_size);
~CGraph(void);
void AddMap(int v1, int v2, int weight);
void AddEndVert(int v2, int weight);
private:
list<edge> List;
int size;
public:
CNode* verts;
};
I'm reading vertices from a file, and that works. My problem is I am having trouble creating an adjacency list based on the code given. I'm trying to use pointers first that points to a list and it is not working correctly. I don't know how to create my pointers to the list without writing over them.
void CMap::SetDirGraph(string command) {
istringstream buffer(command)
char ch;
int num, vert1, vert2, weight; //specify vertices and weight and number of vertices
buffer>>ch; //throw away first character (not needed)
buffer>>num // size of vertices
while(!buffer.eof()) { // keep reading until end of line
buffer>>v1; // vertex start
buffer>>v2; // vertex end
buffer>>weight;
m_myMap = new CGraph(map_size); //initialize m_myMap.
m_myMap->verts->m_vert = v1; // mymap->verts->vert points to first edge
m_myMap->AddMap(v1, v2, weight); // create list?
m_myMap->AddEndVert(v2, weight); //create list? push v2 and weight on my list using my list.
}
}
I've tried several different ways and I keep confusing myself, any point in the right direction would be awesome.
EDIT:
I have more code too if needed to be produced, just publishing the main stuff.
What I mean by "not working" is that I am just writing over the previous vertex. I don't know if I should create an array using m_myMap (tried and still writes over and get a memory error as well). No compiler errors.
I don't know how to create my pointers to the list without writing over them.
Apart from your application, the answer to this question is the new operator, which I assume you are aware of, since you used it within your example code. Code like int * a = new int(42); allocates memory for an int on the heap and you are responsible for cleaning it up when it is not needed anymore. You thereby have full control over how long a variable will be available. In int x = 42; int * a = &x; on the other hand, x will automatically be cleaned up when it runs out of scope, and a will be a pointer to a memory block that has no meaningful data in it anymore. If you try to dereference it, you will encounter undefined behavior, and, if you are lucky, your program will blow up.
If you can use the C++11 standard, or a library that offers smart pointers, you should prefer those over managing the pointer yourself whenever possible. A smart pointer is an object that holds the allocated memory and frees it automatically when it is destructed. More specific information depends heavily on which sort of smart pointer you are using. The reason for using smart pointers is that doing the management yourself is tedious and error prone. If you do not delete your pointers you had allocated, your application will keep on allocating more memory until it blows up some day (depending on how often and how much memory you allocate); this is called leaking. If you call delete more than once, your program will bail out as well. Here is an example of C++11 shared_ptr in your application:
class CMap
{
private:
std::shared_ptr<CGraph> m_myMap;
// etc.
};
// in SetDirGraph
m_myMap.reset( // if the smart pointer has previously been managing
// memory, it will free it before allocating new
new CGraph(map_size) // allocate CGraph as before
);
Besides that, what hopefully answers your question, I have run into several potential problems concerning your code:
Definitely wrong:
In SetDirGraph you set m_myMap->verts->m_vert = v1. m_myMap->verts is a pointer. You have freshly created m_myMap and thus verts is not initialized, hence pointing at a random block of memory. You then try to dereference it by m_myMap->verts->m_vert = v1. This cannot work. You need to create verts first, i.e. verts = new CNode;.
typedef struct edges { /* etc */ } edge; is a C construct and there is no need for the typedef wrapper in C++. It does work and all, but it is really redundant and lots of those constructs just pollute the namespace you are working in.
Do you really need pointers in the first place? Your provided snippets do not hint at why you would need to use them. You will want to reduce usage of pointers to a minimum (or at least use smart pointers, see above)