Reputation: 409
I'm new to C++ so bear with me.
I made a struct that looks like this:
struct node{
double startPoint;
double endPoint;
vector<node*> children;
void addChild(node *aNode){
children.push_back(aNode);
}
void addPoints(double start, double end){
startPoint = start;
endPoint = end;
}
};
Down the line in my program, I have the following:
vector<node*> data;
....
node *temp = (node*)malloc(sizeof(node));
temp->addPoints(lexical_cast<double>(numbers[0]), lexical_cast<double>(numbers[1]));
data[index]->addChild(temp);
where "Index" is a index of the vector data. the lexical_cast
stuff is taking those numbers from string to doubles.
Everything works until the addChild(temp)
line.
The terminal spit this out:
First-chance exception at 0x585b31ea (msvcr90d.dll) in Tree.exe: 0xC0000005: Access violation reading location 0xcdcdcdc1.
Unhandled exception at 0x585b31ea (msvcr90d.dll) in Tree.exe: 0xC0000005: Access violation reading location 0xcdcdcdc1.
But I have no idea how to deal with that.
Upvotes: 4
Views: 2523
Reputation: 18750
node
instead of a node*
in your vector so you don't have to manage the memory on your own. this is C++ so you don't have to malloc the space for a node you can use new like so:
Node * n = new Node();
New is much better because it calls the constructor and allocates space, whereas malloc just does the latter.
You haven't shown much of your code, but I would restructure the node class like this.
struct node{
double startPoint;
double endPoint;
vector<node> children;
node(){} //add default constrcutor
void addChild(node aNode){
children.push_back(aNode);
}
node & operator=(const node & n) {
startPoint = n.startPoint;
endPoint = n.endPoint;
return *this;
}
node(double start, double end): startPoint(start),endPoint(end){
} //in c++ you have constructors which this should have been in the first place
//constructors are used for initializing objects
};
nullptr
avoiding a lot of problems in your code. You also have a constructor now. Now you can add a node like this. node temp(start,end); data[index]=temp;
addPoints
should have been in the first placeUsing the style of coding where you allocate memory on the stack and don't use new is called RAII and is a vital technique for learning c++ and producing exception safe code, this is the main reason I advocate not storing
node*
's
Upvotes: 0
Reputation: 67723
malloc
allocates some space, but doesn't put anything in it. It works fine for plain-old-data structures (or trivially initializable classes), and in C that's all you have.
In C++ you have classes, like std::vector
amongst others, which need to be properly constructed in order to establish some invariants. This is done with a straight declaration for objects with automatic storage duration, but for dynamically-allocated objects you need to use new
instead of malloc
.
For example,
std::vector<int> global; // (1)
void foo() {
std::vector<int> local; // (2)
std::vector<int> *bad = malloc(sizeof(*bad)); // (3)
std::vector<int> *good = new std::vector<int>; // (4)
std::unique_ptr<std::vector<int>> better(new std::vector<int>); (5)
}
foo
exitsbad
for anything, because any method you call will assume the constructor ran already, and it didn't
bad
for anything without explicitly constructing it using placement new. You shouldn't do this though, it's only appropriate where you're doing clever or tricky stuff with custom allocation.foo
has a memory leak)Now, note that your node
class also has a constructor. In this case, it's automatically-generated, and does nothing but call the vector
constructor. Still, you need it to be called, which means using new
for dynamically allocating a node
.
So, your program should probably look more like:
std::vector<std::unique_ptr<node>> data;
...
std::unique_pre<node> temp(new node);
temp->addPoints(...);
data[index]->addChild(temp);
Note I'm assuming data[index]
is valid (I see from addChild
you know how to populate a vector already), and that the single-owner model implemented by unique_ptr
is appropriate.
Upvotes: 2
Reputation: 3974
As far as the code I see, you never add any nodes into the data
array
data.push_back(something);
So accessing data[index]
would be out of the allocated memory of the array. It won't complain until you try to set memory in that block (via addChild
trying to push an element into the children
array).
Upvotes: 1