struct Node{
Node* ch[26];
string str;
Node(){
for(int i = 0; i < 26; i++) {
ch[i] = NULL;
}
str = "";
}
};
class Solution {
public:
vector<string> results;
Node* root;
void insert(Node* p, string s) {
int len = s.size();
for(int i = 0; i < len; i ++) {
if(p->ch[s[i] - 'a'] == NULL) {
p->ch[s[i] - 'a'] = new Node();
}
p = p->ch[s[i] - 'a'];
}
p->str = s;
}
vector<string> wordSearchII(vector<vector<char> > &board, vector<string> &words) {}
}
This is the Trie I defined for my problem. The "root" and "vector result" are both member variables of Solution. The question I want to ask is that why I must "new Node()" before I use root. I do not need to "new vector" before I use results. I understand that the Solution will call default constructor and then "results" will call its default constructor. Why couldn't root use the default constructor of Node?
I happen to realize that my confuse may relate to "pointer". But I still don't understand the details. Can anyone explain about it? I really appreciate it.
root is just a pointer, but you are not assigning anything for it to point at. You need to allocate a new Node object and then assign the address of that object to root, eg:
class Solution {
public:
vector<string> results;
Node* root;
Solution() {
root = new Node;
}
~Solution() {
delete root;
}
...
};
Otherwise, don't make root be a pointer at all:
class Solution {
public:
vector<string> results;
Node root;
...
};
On a side note, your Node class needs a destructor to destroy any child nodes that are added to it:
struct Node{
Node* ch[26];
string str;
Node(){
for(int i = 0; i < 26; i++) {
ch[i] = NULL;
}
}
~Node(){
for(int i = 0; i < 26; i++) {
delete ch[i];
}
}
};
In
Node* root;
The * means that root is a pointer to a Node object, it is not an actual Node object itself. The only storage a pointer has is enough to hold the memory address of whatever the pointer is pointing at. A pointer has to point at something. Right now, you have no idea what root points at, and this is... bad. You have no idea what you'll get if you try to read from it, and you have no idea what you'll smash if you try to write to it. You need to assign something for root to point at, and if that's a new Node(), so be it, but it could also be a pre-existing Node, or a Node in automatic storage (AKA somewhere on the stack).
On the other hand, in
vector<string> results;
results is not a pointer to a vector object. It is the actual vector object. It is the storage. There is no need to allocate memory for it, simply declaring it on the stack allocates everything for it and calls its default constructor.
Related
I'm creating an implementation of a Trie with a TrieNode struct which is an individual node and a TrieSet class which is the complete tree. Here is the signature of my TrieNode:
struct TrieNode {
TrieNode(bool in, TrieNode *p);
~TrieNode();
void deleteChildren(TrieNode *node);
bool isLeafNode();
bool inSet;
TrieNode *parent;
TrieNode *children[30];
};
I'm trying to define the destructor which first recursively deletes all the children and then finally deletes the node, but I'm getting a segmentation fault. Here is the code for my constructor, destructor and its helper function:
TrieNode::TrieNode(bool in, TrieNode *p)
{
inSet = in;
parent = p;
}
TrieNode::~TrieNode()
{
for(int i = 0; i < 30; i++)
{
if(children[i] != nullptr)
{
delete children[i];
}
}
}
Any help would be appreciated, thanks!
The children array is uninitialized, so the data will be random garbage and trying to delete them Undefined Behavior, and likely a crash.
Calling delete node in deleteChildren is wrong, as it results in a recursive destructor call (just like calling delete this from within the destructor).
There may be other issues. I haven't looked extensively.
I have a struct like this:
struct ClientNode
{
string name;
int flightnumber;
int clientno;
ClientNode * right;
ClientNode* left;
};
then I have declared a pointer of this struct:
ClientNode* root = new ClientNode;
in a function I have initialized clientno for root like this:
root->clientno = 11;
and then I want to send root as an argument to a function:
ClientNode newnode;
root = Insert_to_AVL_Tree(&newnode, root);
and here is my Insert_to_AVL_Tree:
ClientNode* clientclass::Insert_to_AVL_Tree(ClientNode* Node, ClientNode* root)
Here is where the error happens, I have initialized root->clientno but it seems that it changes when I pass it to another function thus it can't compare to values in the if, also node->clientno has the correct value that has been read from a file in another part of my code:
if (Node->clientno < root->clientno)
root->left = Insert_to_AVL_Tree(Node, root->left);
what is the correct way to get the root->clientno value in another function?
here is the value shown for root->clientno
here is the value for node->cleintno
For passing Pointer to functions the best way I use is double pointer
void clear(int **p)
{
*p = 0;
}
int main()
{
int* p;
clear(&p);
return 0;
}
I'm trying to implement some basic Tree structure for sea navigation algorithm.
I've got something like this:
class Point {
float lng;
float lat;
};
class Node {
public:
Node *parent;
std::list<Node> *childern;
Point *point;
Node::Node(Node *prnt, Point *point);
void Node::calcChildrens();
};
Node::Node(Node *prnt, Point *point) {
this->parent = prnt;
this->point = point;
this->childern = nullptr;
}
int counter = 0;
void Node::calcChildrens() {
for (int i = 0; i < 5; i++) {
Point *p = new Point(someValX, someValY);
Node n = Node(this, p);
if (this->childern == NULL) this->childern = new list<Node>;
this->childern->push_back(n);
if (counter < 4) {
counter++;
n.calcChildrens();
}
}
This should create 4 level's of recursion tree, but creates just one level of tree.
I think it's the problem with parent pointers but i can't realize what really is happening.
There are several issues with your code
struct Point { // we want public access, hence struct not class
float lng;
float lat;
};
struct Node { // if all members a public, use struct
Node*parent = nullptr; // provide default argument
std::list<Node> children; // hold a list, not a pointer to one
Point point; // hold a Point, not a pointer to one
Node(Node*p, const Point&x)
: parent(p), point(x) {} // use initialization list
void calcChildren(size_t levels); // avoid global variable counter; use correct English
};
void Node::calcChildren(size_t levels)
{
if(levels--)
for(int i = 0; i < 5; i++) { // really 5? 4 children seems more logical
// construct child in place, avoid copying a Node
children.emplace_back(this, Point{someValX, someValY});
children.back().calcChildren(levels);
}
}
You may also keep track of the tree depth as a data member for each node. Unfortunately, as you failed to provide a Minimal Complete and Verifiable Example, I cannot test this here.
Note also that your code had no destructor for Node, leaking all memory allocated with a node. This problem disappears when avoiding those pointers is favour of objects. As Nodes are allocated on the heap anyway, this is the logical and correct way of doing things in C++.
Note further that you may want to avoid keeping the children in a linked list (linked lists are to be avoided if efficiency is important). You may instead use an array or vector. In this case
struct Node { // if all members a public, use struct
Node*parent = nullptr; // provide default argument
std::vector<Node> children; // hold a vector, not a pointer to one
Point point; // hold a Point, not a pointer to one
Node(Node*p, const Point&x)
: parent(p), point(x) {} // use initialization list
void calcChildren(size_t levels); // avoid global variable counter; use correct English
};
void Node::calcChildren(size_t levels)
{
if(levels--) {
children.reserve(5);
for(int i = 0; i < 5; i++) {
// construct child in place, avoid copying a Node
children.emplace_back(this, Point{someValX, someValY});
children.back().calcChildren(levels);
}
}
}
I have this C++ struct:
struct Node {
char symbol;
unsigned int index;
vector<Node*> next;
// Constructors
Node():symbol('$'), index(0), next(0) {}
Node(char &c, const unsigned int &ind):symbol(c), index(ind), next(0) {}
// Add a new character
Node* add(char &c, const unsigned int &num) {
Node *newChar = new Node(c, num);
next.push_back(newChar);
return newChar;
}
// Destructor
~Node() {
for (int i = 0; i < next.size(); i++)
delete next[i];
}
};
(I know it might be better to make it a class but let's consider it as it is).
I'm not quite sure if I wrote the correct destructor for this. In the main function I'm using a root node:
Node *root = new Node();
Although the code won't leak memory (as long as you delete the root node in main), it isn't really optimal.
You should avoid new and delete and instead prefer smart pointers. In this case, use unique_ptr.
Also, don't create the root node on the heap, just create it normally like so:
Node root;
// use root normally
You also don't follow the rule of five properly, and you won't even need to worry about it if you used unique_ptr since you wouldn't have a custom dtor. There's also no reason to take the c and ind by ref and const ref, just pass them by value (because you don't even change them, and its as cheap passing by value as by ref for primitives).
With these changes, the code looks like this
struct Node {
char symbol;
unsigned int index;
vector<std::unique_ptr<Node>> next;
// Constructors
Node():symbol('$'), index(0){}
Node(char c, unsigned int ind):symbol(c), index(ind) {}
// Add a new character
Node* add(char c, unsigned int num) {
next.push_back(std::make_unique<Node>(c, num));
return next.back().get();
}
};
This is not a real question, since I've already solved the problem myself, but I still need some clarifications about the mechanism behind assigning an array's address to a pointer of the same type when the array is a class member of a nested class.
The following code is fully functioning, although it may lack some error_check. It is only meant to show how I made my (real) program work.
HEADER (linkedList)
class linkedList
{
public:
linkedList();
~linkedList();
int* getArray();
void forward();
private:
class listNode
{
public:
listNode();
~listNode();
friend class linkedList;
private:
int array[3];
listNode* next;
};
listNode *first;
listNode *current;
};
CPP (linkedList)
linkedList::linkedList()
{
first = new listNode;
current = first;
}
//~~~~~~~~~~~~
linkedList::~linkedList()
{
delete first;
first = 0;
current = 0;
}
//~~~~~~~~~~~~
int* linkedList::getArray()
{
if (current)
{
return &(current->array[0]);
}
}
//~~~~~~~~~~~~
void linkedList::forward()
{
if (current->next)
{
current = current->next;
}
}
//-------------------------
//-------------------------
//-------------------------
linkedList::listNode::listNode()
{
next = 0;
for (int i = 0; i < 3; i++){array[i]=((i+1)*3);}
}
//~~~~~~~~~~~~
linkedList::listNode::~listNode()
{
}
CPP (main)
#include <iostream>
#include "linked_list.h"
using namespace std;
int main()
{
linkedList list;
int *myArray;
myArray = list.getArray();
for (int i = 0; i < 3; i++){cout << myArray[i] << " ";}/**/cout << "\n\n";
return 0;
}
The real program is meant to move through a linked list made of nodes which contain 3 integer values in an array of int type, retrieve the three values and use them as parameters for some other functions.
Now, to do so I have to return the address to the first element of the array contained in the node through an accessor.
Apparently, the only way to do it is by returning the reference to the first element of the array in the node to which the linkedList's member variable current points to:
return &(current->array[0]);.
Why?
I've got to this solution through trial and error with very little knowlegde of the reasons that brought me to build this expression as it is.
Usually, when you want to assign the address of an array to a pointer, you just do so:
int main()
{
int array[3];
int* pArray;
pArray = array;
}
And that's it, because the name of the array itself is enough to retrieve the address of its first element.
The exact same result can be achieved by doing this (tested):
int main()
{
int array[3];
int* pArray;
pArray = &(array[0]);
}
Both methods are also valid when the accessor returns the address from a member variable of its own class.
But why, when accessing the member variable of a nested class, I'm forced to use the second method?
What are the logic stages that make it the only viable method?
But why, when accessing the member variable of a nested class, I'm forced to use the second method?
You aren't:
return current->array;
and
return &(current->array[0]);
Both do the same thing when the return type is int*. You aren't forced to use the second way.
Also, there's a bug in getArray. You don't return anything if current is null.
To be pedantic...
Apparently, the only way to do it is by returning the reference to the first element of the array in the node to which the linkedList's member variable current points to:
return &(current->array[0]);.
You're returning the address i.e. a pointer. Reference means something else.