Pointer to an array of pointers.

I am trying to figure out a run-time exception I get on line 53 below. I am trying to create a new Node object using a pointer to an array of Node*. The Node* are all initialized to 0 in the constructor. Can anyone spot the error?

The run-time exception is:
Unhandled exception at 0x00df249f in LAN.exe: 0xC0000005: Access violation writing location 0xcccccccc.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// Main.h
int main() {
	Network network;
	const Node node;
	network.add(node);
	return EXIT_SUCCESS;
}

// Network.h
class Network {
public:
	Network();
	Network(const unsigned);
	bool add(const Node&);
	const unsigned size() const;
	~Network();

private:
	Node** nodes;
	unsigned node_count;
	unsigned capacity;
};

// Network.cpp
#include "Network.h"

Network::Network()
: node_count(0), capacity(10) {
	Network(10);
}

Network::Network(const unsigned init_capacity)
: node_count(0), capacity(init_capacity) {
	nodes = new Node*[capacity];
	for (unsigned i = 0; i < capacity; i++) {
		nodes[i] = 0;
	}
}

Network::~Network() {
	for (unsigned i = 0; i < node_count; i++){
		delete nodes[i];
	}
	delete [] nodes;
}

bool Network::add(const Node& node) {
	for (unsigned i = 0; i < node_count; i++) {
		if (nodes[i] == &node) {
			return false;
		}
	}
	nodes[node_count++] = new Node;
	return true;
}
node_count is never checked to be <= capacity, so the buffer is being overflowed.
I don't see how this could be causing the problem. In main() I only add one node and node_count is initialized to 0, while capacity is initialized to 10; I have verified those value in the debugger just before line 53 executes. I can understand this being a problem for the 11th node, but not the first 10.
I need to see the implementation of Node, but I already see a problem with Network::Network(). Constructors can't be called. I don't know how that compiled at all.
I was trying to save space by not including some code. Here is all of it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Main.cpp
#include <iostream>
#include <cstdlib>
#include "Network.h"

using namespace std;

int main() {
	Network network;
	Node node;
	network.add(node);
	system("pause");
	return EXIT_SUCCESS;
}

// Network.h
#ifndef NETWORK_H
#define NETWORK_H
#include "Node.h"

class Network {
public:
	Network();
	Network(const unsigned);
	bool add(const Node&);
	//const Node& remove(const Node&);
	const unsigned size() const;
	~Network();

private:
	void realloc();

	Node** nodes;
	unsigned node_count;
	unsigned capacity;
};
#endif

// Network.cpp
#include "Network.h"

Network::Network()
: node_count(0), capacity(10) {
	Network(10);
}

Network::Network(const unsigned init_capacity)
: node_count(0), capacity(init_capacity) {
	nodes = new Node*[capacity];
	for (unsigned i = 0; i < capacity; i++) {
		nodes[i] = 0;
	}
}

Network::~Network() {
	for (unsigned i = 0; i < node_count; i++){
		delete nodes[i];
	}
	delete [] nodes;
}

bool Network::add(const Node& node) {
	for (unsigned i = 0; i < node_count; i++) {
		if (nodes[i] == &node) {
			return false;
		}
	}
	if (node_count == capacity) {
		realloc();
	}
	nodes[node_count++] = new Node;
	return true;
}

void Network::realloc() {
	Node** new_nodes = new Node*[capacity *= 2];
	unsigned i = 0;
	for (; i < node_count; i++) {
		new_nodes[i] = nodes[i];
	}
	for (; i < capacity; i++) {
		new_nodes[i] = 0;
	}
	delete [] nodes;
	nodes = new_nodes;
}

const unsigned Network::size() const {
	return node_count;
}

// Node.h
#ifndef NODE_H
#define NODE_H
class Node {
public:
	Node();
	~Node();

private:
	Node* nodes;
	const unsigned id;
	static unsigned id_count;
};
#endif

// Node.cpp
#include "Node.h"

unsigned Node::id_count = 0;

Node::Node()
: id(id_count++), nodes(0) {
}

Node::~Node() {
}
It definitely compiles. I suppose I should have just included it all. Anyway, the run-time error now occurs on line 71.
Line 44 does essentially nothing. You'll have to duplicate the code from your other constructor, or better yet:

1
2
3
4
class Network {
  public:
      explicit Network( unsigned int cap = 10 );
};


And kill two birds with one stone.

(Essentially your default constructor is not initializing nodes, and it is setting capacity to 10 whereas it is in fact zero.)
Thanks, that constructor was the problem.
Topic archived. No new replies allowed.