Method is being called on class with uninitialized attributes despite constructors - c++

Premise: suppose I have a rectangular subset of 2D space and a collection of points, all with different x-values, in this subset. In the interest of the optimization of an algorithm as yet unwritten, I want to split my box into cells according to the following process: I halve my rectangle into 2 equal parts along the x-axis. Then I repeatedly halve each sub-rectangle until every cell contains either 1 point or none at all.
In this illustration the vertical lines represent the “halving process” and the lines are ordered by darkness (darker is newer).
First I’ll define two basic classes:
class Point{
private:
double x;
double y;
public:
// [...]
// the relevant constructor and getter
// overloaded operators +, -, * for vector calculations
};
class Box{
private:
Point bottom_left_point;
double width;
double height;
public:
Box(Point my_point, double my_x, double my_y) : // constructor
bottom_left_point(my_point), width(my_x), height(my_y){}
bool contains(const Point& p); // returns true iff the box contains p in the geometric sense
Box halve(bool b) const; // takes a boolean as input and returns the left half-rectangle for false, and the right half-rectangle for true
};
Now to implement the “halving algorithm” I’ll need a binary tree-like structure. Each node will represent a sub-cell of the rectangle (with the root node representing the total rectangle). A node may have two children, in which case the children represent its left and right halves. A node may also have a pointer to a particle which exists in the cell. The ultimate idea will be to start with an empty tree and insert the points in, one by one using a method insert(Point* to_be_inserted).
So I’ll define the following recursive class, whose private attributes are rather self-explanatory:
class Node;
class Node{
private:
enum node_type{ INT, EXT, EMPTY };
node_type type;
// type == INT means that it is an interior node, i.e. has children
// type == EXT means that it is an exterior node, i.e. has no children but contains a point
// type == EMPTY means that it has no children and no point
std::array<Node*,2> children;
Box domain; // the geometric region which is being represented
Point* tenant; // address of the particle that exists in this cell (if one such exists)
public:
Node(Box my_domain) :
type(EMPTY), children({nullptr}), domain(my_domain){}
//
// to be continued...
The first order of business is to define a subdivide() method which endows my node with two children:
void Node::subdivide(void){
type = INT;
children[0] = new Node(domain.halve(false));
children[1] = new Node(domain.halve(true));
}
Now everything is in place to write the crux of this whole affair, the insert method. Since it will be written recursively, the easiest solution is to have a boolean return type which tells us if the insertion was a success or failure. With this in mind, here’s the code:
bool Node::insert(Point* to_be_inserted){
if(not domain.contains(*to_be_inserted)) return false;
switch(type){
case INT:{
for(Node* child : children) if(child->insert(to_be_inserted)) return true;
return false;
}
case EXT:{
subdivide();
for(Node* child : children) if(child->insert(to_be_inserted)) break;
tenant = nullptr;
for(Node* child : children) if(child->insert(to_be_inserted)) return true;
break;
}
case EMPTY:{
type = EXT;
tenant = to_be_inserted;
return true;
}
}
throw 1; // this line should not, in, theory ever be reached
}
(Note that, for the sake of abstraction and generality, I have used for loops on the array children when I could have simply written out the two cases.)
Explanation:
First we check if to_be_inserted is in the geometric region represented by this. If not, return false.
If this is an internal node, we pass the point on to the each child until it is successfully inserted.
If this is an external node, that means that we have to split the node in two in order to be able to properly isolate to_be_inserted from the point that currently lives in the node.
First we call multiply().
Then we attempt to insert the current tenant into one of the children (please excuse how obscene this sounds, I assure you that it’s unintentional).
Once that is done, we do the same with to_be_inserted and return the result. (Note that a priori the insertion would be a success at this point because of the preliminary call to box::contains.
Finally, if this is an EMPTY node, we simply have to assign tenant to *to_be_inserted and change type to EXT and we’re done.
Ok, so let's try it out with a simple main:
int main(void){
Box my_box(ORIGIN, 1.0, 1.0); // rectangle of vertices (0,0),(0,1),(1,0),(1,1)
Node tree(box); // initializes an empty tree representing the region of my_box
Point p(0.1, 0.1);
Point q(0.6, 0.7);
tree.insert(&p);
tree.insert(&q);
return 0;
}
This compiles, but upon running the exception at the bottom of insert is thrown after a few calls. How is this possible, given that at no point a Node is constructed without a type value?
Edit: I have noticed, as well as this one, several possible errors which may also occur with small changes in the code:
An inexplicable call to nullptr->insert(something)
A call to insert by the address 0x0000000000000018 which doesn't point to an initialized Node.
The entirety of the code, including a makefile with the relevant debugging flags, can be found at https://github.com/raphael-vock/phantom-call.

Related

C++ n-arry tree with different elements

I want to build a n-arry tree from a document. For that i have 3 different types of elements for the tree:
Struct Nodes
Have a name
can contain other Nodes
Depth
Element Node (Leaf of the tree)
Have a Key
Have a value
Depth
Element Template Node (Leaf of the tree)
Have a placeholder which should be resolved later in the program
Depth
At the moment i think about something like this:
class Node {
public:
Node(int depth);
int depth() const;
private:
int depth_;
};
class StructNode : public Node {
...
private:
std::vector<std::unique_ptr<Node>> children;
};
class ElementNode : public Node {
...
};
class ElementTemplateNode : public Node {
...
};
The Tree will be generated from an File on Startup and reused to create an output string like this:
Structname:
key = value
key = value
Structname:
key = value
Structname:
key = value
...
Where the Key and value where directly read from the ElementNode or read from another file with the value of the placeholder inside the ElementTemplateNode
Is there maybe a better Structure for the Tree? Because with the current one i have to check first if its a StructNode, ElementNode or ElementTemplateNode
This is a typical structure for implementing a tree with different kind of nodes. Another variant would be the composite pattern.
The problem that you describe, is usually caused by asking the nodes about what they know, instead of telling them what to do. If you'd do it the other way round (tell, don't ask), you could get rid of those checks and benefit from polymorphism.
The different kind of nodes inherit from Node. You could design your tree using a uniform interface, with virtual functions defined for Node which then can be overridden for the different types of nodes. Calling the method would then do the right things, without need for a manual type check. For generating the output string, you'd tell the root node to generate a string. If it's a structure, it would add the heading and tell its children to generate a string, but if it's a leaf it would just add the key/value pair to the string. No need from outside to know anything about each node.
If the operation of exploring the tree shall not be implemented by the tree itself, the usual approach is to use a visitor pattern. The big advantage is that you write the vistor once, and it's then easy to specialize a new kind of visitor for different algorithms. Again, no need to check the type of the nodes. The pattern makes sure that the right elementary function is called for the right type of node.

Converting subclass to base class?

I am working on a problem in which we have a binary search tree made of nodes. The node's attributes consist of string, pointer to left node, and pointer to right node. I have a class called TransactionNode that is a subclass of node. TransactionNode has an int (for amount sold) as well as the same attributes from node class. I have a function called findBiggest that looks for the highest amount sold from TransactionNode and returns a reference to that TransactionNode. My problem is how do I convert something that is from the node class to TransactionNode? (I am avoiding changing the nodes in the binary search tree to TransactionNodes)
TransactionNode & BST::findBiggest()
{
TransactionNode * rightSide;
rightSide = this->mpRoot;
while (rightSide != nullptr)
{``
//find biggest transaction
}
return rightSide;
}
In general, if you need to check if an object pointed to by a base class pointer is of the derived class type, you use dynamic_cast
In your case you could try inside your while loop:
TransactionNode* txnNode = dynamic_cast<TransactionNode*>(rightSide);
if (txnNode != nullptr)
{
int amtSold = txnNode->GetAmountSold();
}
You may also consider having a virtual method in the base class and rely on polymorphism. Usually that is a preferred way over dynamic_cast. However, it may be that your Node class is too high level and does not need to support a "GetAmountSold()" method, but that is something you can decide.

Design and implementation of a 2-3 tree with polymorphism

I have to implement a 2-3 tree using a base class of a node and derived class of leaf and an innernode (i.e both "are-a" node).
But I don't understand how to start with the insertion in simple cases. Since we call the methods of node to insert, how is it supposed to know if what we insert needs to be an innernode or a leaf? And how does a node supposed to change itself to a leaf or an innernode?
Any tips/ideas on how to approach this?
Here's the structure, I didn't get very far though.
typedef int TreeKey;
class node {
public:
virtual ~node() {}
virtual void insert(TreeKey k, string d);
virtual void deletenode(TreeKey k);
virtual void findnode();
virtual node * findnode(TreeKey key);
protected:
struct info {
TreeKey key;
string data;
};
node* parent=nullptr;
};
class leaf : node {
info i;
public:
virtual void insert(TreeKey k, string d);
};
class innerNode : node {
vector<info> inf;
vector<node*> vect;
public:
virtual void insert(TreeKey k, string d);
};
Note: in this 2-3 tree, the data sits only in the leaves.
One way of doing things is as follows. There are others.
Have 4 separate classes: a 2-leaf-node, a 3-leaf-node, a 2-internal-node and a 3-internal-node. This solution gets rid of vectors and so minimises dynamic allocations.
One inserts an element, not a node. Each node knows what to do with inserted element. An internal node passes the element to one of the child nodes. A leaf node absorbs the element.
A 2-node absorbs an element by becoming a 3-node. A 3-node absorbs an element by becoming two 2-nodes, and passing an element back to its parent to absorb. The parent then itself changes and may pass an element up. This continues until some 2-node changes to a 3-node (its parent doesn't need to change, only replace its child pointer), or an element propagates all the way back to the root, and a new root is created.
How a node "becomes" something else? It cannot. Instead, it creates the new thing(s) it should become, copies its information to the new thing(s), returns the newly created thing(s) to the caller, and deletes itself. The caller then either replaces its old child with the newly created one, or itself "becomes" something else.
The insert method signature of the node could look like this:
typedef enum {none, expand23, split322} action;
action Node::insert(info& element, Node*& newNode1, Node*& newNode2);
If the node was a 2-node and it became a 3-node, the method creates a new 3-node and passes it back in newNode1. The parent has to replace the corresponding child pointer upon seeing expand23. The parent itself doesn't expand or split, so its insert returns none.
If the node was a 3-node and it splits, the method creates two new 2-nodes and passes them back in newNode1 and newNode2. It also passes back an element for that the parent to absorb. The parent will do either expand23 or split322 depending on what type it is.
If the root returns split322, a new root is created
"in this 2-3 tree, the data sits only in the leaves" — just noticed this remark. I'm not sure how this could ever work. A 2-3 tree has either 1 or 2 data items in each node, not just leaves. It cannot work otherwise. So I pretty much ignore this remark.
If you don't want to have separate classes for 2- and 3-nodes, then you don't need expand23 because a 2-node can turn into a 3-node without having to delete itself. split322 remains the same. I would not use vectors in this case. Since leaf nodes only store copies of keys that exist elsewhere, they can be stored as 3 (smart) pointers to keys (not an array, just 3 separate variables). You distinguish between a 2-node and a 3-node by looking at the third pointer. If it's a nullptr, this is a 2-node. Same thing about data in the leaves, store it in 3 separate pointers.

How to correctly allocate memory for same type of objects

i have this class, its alot like node when creating linked list.
class Element {
public:
int id;
int value;
bool parent;
bool is_ministry;
int children_count;
int children_in;
Element **children; //CHILDREN ARRAY
Element* next; //TO NOT LOSE ELEMENTS
Element(int _id,int _value,int _children_count=0,bool _is_ministry=false){
this->id=_id;
this->value=_value;
this->is_ministry=_is_ministry;
this->children_in=0;
if(_children_count>0)
this->parent=true;
else this->parent=false;
this->children_count=_children_count;
this->next=NULL;
if(_children_count>0){
this->children = new Element*[_children_count];
}
else this->children=NULL;
}
~Element(){
///delete children;
}
};
And i need this object to have an array of pointers to same type of objects, array size varies on the given input - children_count.
Can it be statically created? Values are read from file. I have chosen dynamic approach, but im not sure if its done correctly, because it works, but after i add 3 objects, the whole thing burns down. So im looking for plausible faults.
I am making something like a tree. Where one element has direct access to one level down same type of objects.
EDIT: MORE CODE
void chain_together(Element *_parent, Element *_child){
///CHILDREN_IN is and int which shows currently how much elements are in the array.
if(_parent->children_in>0){
for(int i=0;i<_parent->children_in;i++) ///CHEKING IF THERE ALREADY IS A LINK BETWEEN THEM
if(_parent->children[i]->id != _child->id){
_parent->children[_parent->children_in] = _child;
_parent->children_in++;
}
}else{
_parent->children[_parent->children_in] = _child;
_parent->children_in++;
}
}
Let's take a walk through the chain_together method.
if(_parent->children_in>0){
If the child list is not empty
for(int i=0;i<_parent->children_in;i++)
Visit at all known children
if(_parent->children[i]->id != _child->id){
If this child isn't the child we wish to add, add the child
_parent->children[_parent->children_in] = _child;
_parent->children_in++;
}
}else{
No children. Add the first child
_parent->children[_parent->children_in] = _child;
_parent->children_in++;
}
Walking through the addition of a few children to see what happens...
On the first child
just add them.
On the second child,
they are not the first child
add them
On the third child,
they are not the first child
add them.
they are not the second child
add them.
See the problem? If not...
On the fourth child,
they are not the first child
add them.
they are not the second child
add them.
they are not the third child
add them.
they are not the third child
add them.
This bug would have been trivial to detect by stepping through the code with a debugger. A debugger comes with ever compiler tool kit that's worth using. It is possibly the most important tool you will ever learn to use as a programmer.
Solution:
Test that the added child doesn't match all of the pre-existing children before adding the new child.

How to create method which will know that its instance is in matrix of another class

I'm an absolute beginner in OOP (and C++). Trying to teach myself using resources my university offers for students of higher years, and a bunch of internet stuff I can find to clear things up.
I know basic things about OOP - I get the whole point of abstracting stuff into classes and using them to create objects, I know how inheritance works (at least, probably the basics), I know how to create operator functions (although as far as I can see that only helps in code readability in a sense that it becomes more standard, more language like), templates, and stuff like that.
So I've tried my first "project": to code Minesweeper (in command line, I never created a GUI before). Took me a few hours to create the program, and it works as desired, but I feel like I'm missing a huge point of OOP in there.
I've got a class "Field" with two attributes, a Boolean mine and a character forShow. I've defined the default constructor for it to initialize an instance as an empty field (mine is false), and forShowis . (indicating a not yet opened filed). I've got some simple inline functions such as isMine, addMine, removeMine, setForShow, getForShow, etc.
Then I've got the class Minesweeper. Its attributes are numberOfColumns, ~ofRows, numberOfMines, a pointer ptrGrid of type Mine*, and numberOfOpenedFields. I've got some obvious methods such as generateGrid, printGrid, printMines (for testing purposes).
The main thingy about it is a function openFiled which writes the number of mines surrounding the opened field, and another function clickField which recursively calls itself for surrounding fields if the field which is currently being opened has 0 neighbor mines. However, those two functions take an argument -- the index of the field in question. That kinda misses the point of OOP, if I understand it correctly.
For example, to call the function for the field right to the current one, I have to call it with argument i+1. The moment I noticed this, I wanted to make a function in my Field class which would return a pointer to the number right to it... but for the class Field itself, there is no matrix, so I can't do it!
Is it even possible to do it, is it too hard for my current knowledge? Or is there another more OOP-ish way to implement it?
TLDR version:
It's a noob's implemetation of Minesweeper game using C++. I got a class Minesweeper and Field. Minesweeper has a pointer to matrix of Fields, but the navigation through fields (going one up, down, wherever) doesn't seem OOP-ishly.
I want to do something like the following:
game->(ptrMatrix + i)->field.down().open(); // this
game->(ptrMatrix + i + game.numberOfColumns).open(); // instead of this
game->(ptrMatrix + i)->field.up().right().open(); // this
game->(ptrMatrix + i + 1 - game.numberOfColumns).open(); // instead of this
There are a couple of ways that you could do this in an OOP-ish manner. #Peter Schneider has provided one such way: have each cell know about its neighbours.
The real root of the problem is that you're using a dictionary (mapping exact coordinates to objects), when you want both dictionary-style lookups as well as neighbouring lookups. I personally wouldn't use "plain" OOP in this situation, I'd use templates.
/* Wrapper class. Instead of passing around (x,y) pairs everywhere as two
separate arguments, make this into a single index. */
class Position {
private:
int m_x, m_y;
public:
Position(int x, int y) : m_x(x), m_y(y) {}
// Getters and setters -- what could possibly be more OOPy?
int x() const { return m_x; }
int y() const { return m_y; }
};
// Stubbed, but these are the objects that we're querying for.
class Field {
public:
// don't have to use an operator here, in fact you probably shouldn't . . .
// ... I just did it because I felt like it. No justification here, move along.
operator Position() const {
// ... however you want to get the position
// Probably want the Fields to "know" their own location.
return Position(-1,-1);
}
};
// This is another kind of query. For obvious reasons, we want to be able to query for
// fields by Position (the user clicked on some grid), but we also would like to look
// things up by relative position (is the cell to the lower left revealed/a mine?)
// This represents a Position with respect to a new origin (a Field).
class RelativePosition {
private:
Field *m_to;
int m_xd, m_yd;
public:
RelativePosition(Field *to, int xd, int yd) : m_to(to), m_xd(xd),
m_yd(yd) {}
Field *to() const { return m_to; }
int xd() const { return m_xd; }
int yd() const { return m_yd; }
};
// The ultimate storage/owner of all Fields, that will be manipulated externally by
// querying its contents.
class Minefield {
private:
Field **m_field;
public:
Minefield(int w, int h) {
m_field = new Field*[w];
for(int x = 0; x < w; x ++) {
m_field[w] = new Field[h];
}
}
~Minefield() {
// cleanup
}
Field *get(int x, int y) const {
// TODO: check bounds etc.
// NOTE: equivalent to &m_field[x][y], but cleaner IMO.
return m_field[x] + y;
}
};
// The Query class! This is where the interesting stuff happens.
class Query {
public:
// Generic function that will be instantiated in a bit.
template<typename Param>
static Field *lookup(const Minefield &field, const Param &param);
};
// This one's straightforwards . . .
template<>
Field *Query::lookup<Position>(const Minefield &field, const Position &pos) {
return field.get(pos.x(), pos.y());
}
// This one, on the other hand, needs some precomputation.
template<>
Field *Query::lookup<RelativePosition>(const Minefield &field,
const RelativePosition &pos) {
Position base = *pos.to();
return field.get(
base.x() + pos.xd(),
base.y() + pos.yd());
}
int main() {
Minefield field(5,5);
Field *f1 = Query::lookup(field, Position(1,1));
Field *f0 = Query::lookup(field, RelativePosition(f1, -1, -1));
return 0;
}
There are a couple of reasons why you might want to do it this way, even if it is complicated.
Decoupling the whole "get by position" idea from the "get neighbour" idea. As mentioned, these are fundamentally different, so expose a different interface.
Doing it in this manner gives you the opportunity to expand later with more Query types in a straightforwards fashion.
You get the advantage of being able to "store" a Query for later use. Perhaps to be executed in a different thread if it's a really expensive query, or in an event loop to be processed after other events, or . . . lots of reasons why you might want to do this.
You end up with something like this: (C++11 ahead, be warned!)
std::function<Field *()> f = std::bind(Query::lookup<RelativePosition>,
field, RelativePosition(f1, -1, -1));
. . . wait, what?
Well, what we essentially want to do here is "delay" an execution of Query::lookup(field, RelativePosition(f1, -1, -1)) for later. Or, rather, we want to "set up" such a call, but not actually execute it.
Let's start with f. What is f? Well, by staring at the type signature, it appears to be a function of some sort, with signature Field *(). How can a variable be a function? Well, it's actually more like a function pointer. (There are good reasons why not to call it a function pointer, but that's getting ahead of ourselves here.)
In fact, f can be assigned to anything that, when called, produces a Field * -- not just a function. If you overload the operator () on a class, that's a perfectly valid thing for it to accept as well.
Why do we want to produce a Field * with no arguments? Well, that's an execution of the query, isn't it? But the function Query::lookup<RelativePosition> takes two arguments, right?
That's where std::bind comes in. std::bind essentially takes an n-argument function and turns it into an m-argument function, with m <= n. So the std::bind call takes in a two-place function (in this case), and then fixes its first two arguments, leaving us with . . .
. . . a zero-argument function, that returns a Field *.
And so we can pass around this "function pointer" to a different thread to be executed there, store it for later use, or even just repeatedly call it for kicks, and if the Position of Fields was to magically change for some reason (not applicable in this situation), the result of calling f() will dynamically update.
So now that I've turned a 2D array lookup into a mess of templates . . . we have to ask a question: is it worth it? I know this is a learning exercise and all, but my response: sometimes, an array is really just an array.
You can link the four neighbours to the cell via pointers or references. That would likely happen after the playing field has been created. Whether that's good or bad design I'm not sure (I see the same charme though that you see). For large fields it would increase the memory footprint substantially, because a cell probably doesn't hold that much data besides these pointers:
class Cell
{
// "real" data
Cell *left, *right, *upper, *lower;
// and diagonals? Perhaps name them N, NE, E, SE, S...
};
void init()
{
// allocate etc...
// pseudo code
foreach r: row
{
foreach c: column
{
// bounds check ok
cells[r][c].upper = &cells[r-1][c];
cells[r][c].left = &cells[r][c-1];
// etc.
}
}
// other stuff
}