Compile time error in dereferencing the map pointer - c++

#include <iostream>
#include <map>
#include <vector>
using namespace std;
struct node{
int data;
struct node *left;
struct node *right;
};
struct node* newNode (int data)
{
struct node *temp = new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}
void printVerticalUtil(struct node *root, map<int, vector<struct node*> > *m, int index){
if(root == NULL)
return;
*m[index].push_back(root); // compiler error
}
int main(){
struct node *root, *res;
root = newNode(1);
map<int, vector<struct node*> > m;
printVerticalUtil(root, &m, 0)
}
I am passing map address in printVerticalUtil() function using pointer, I am getting compiler error at *m[index].push_back(root); I can't understand the error (no matching function to call)
I know if i pass by reference , it would work but i want to know what is wrong with passing by pointer here.

Because of operator precedence the expression
*m[index].push_back(root)
is the same as
*(m[index].push_back(root))
In other words, you try to dereference what the push_back function returns, and since it doesn't returns anything that can be referenced (it doesn't return anything at all) you get a compiler error.
What you want is
(*m)[index].push_back(root)

It's about operator precedence. You would have to deference the pointer first, to get at the map
(*m)[index].push_back(root);

Related

Threaded tree memory allocation error: cannot convert node* to node

I am writing this in c++ and getting this error "cannot convert 'createNode(int)::DTBinarytree*' to 'DTBinaryTree*' in
initialization*"
#include <iostream>
#include <cstdlib>
using namespace std;
struct DTBinaryTree{
int Ltag;
int data;
int Rtag;
struct DTBinaryTree* left;
struct DTBinaryTree* right;
};
struct DTBinaryTree* createNode(int data){
struct DTBinaryTree* root = (struct DTBinarytree**)malloc(sizeof(struct DTBinaryTree));
root->Ltag = 0;
root->data = data;
root->Rtag = 0;
root->right = root->left = NULL;
return root;
};
can you please help me out where i am doing wrong?
I tried making first line of createnode as
struct DTBinaryTree* root = (struct DTBinarytree*)malloc(sizeof(struct DTBinaryTree*));
but it showed one more note as
"class type 'createNode(int)::DTBinarytree' is incomplete"
You are using malloc which, prior to C++20, does not start the lifetime of objects.
You cast the return from malloc to a DTBinaryTree** (assuming DTBinarytree** was a typo) and try to assign it to a DTBinaryTree*. They are not the same, just like an int* is not the same as an int**.
You don't have to use struct DTBinaryTree other than when defining the class. Simply use DTBinaryTree.
Don't use NULL, use nullptr.
It looks like C code. In C++, you should probably make a constructor instead:
struct DTBinaryTree {
int Ltag = 0;
int data;
int Rtag = 0;
DTBinaryTree* left = nullptr;
DTBinaryTree* right = nullptr;
DTBinaryTree(int Data) : data(Data) {}
};
You can now create DTBinaryTree instances:
DTBinaryTree* foo = new DTBinaryTree(123); // foo->data == 123
delete foo;
or as an automatic variable:
DTBinaryTree foo(123);

Tree implementation in C++: Cannot convert Node to int* Ask Question

I'm currently working on my homework. Below is the program for construction of binary tree which I wrote. I'm getting the error that, "cannot convert 'node' to 'int*' in assignment". Can you please help me out here?**
#include<iostream>
#include<conio.h>
struct node
{
char data;
int *left,*right;
};
int main()
{
node *T; //ROOT of tree
node *p,*q; //address of first node in T
T=new node;
T->left=NULL;
T->right=NULL;
T->data='A';
p=new node;
p->left=NULL;
p->right=NULL;
p->data='B';
T->left=&p;
p=new node;
p->left=NULL;
p->right=NULL;
p->data='C';
T->right=&p;
q=new node;
q->left=NULL;
q->right=NULL;
q->data='D';
p->left=&q;
return 0;
}```
Change your structure definition to
struct node
{
char data;
node *left,*right; // <- node * here
};
Tree node has a recursive definition.
Change your structure as #TarekD suggested, the problem is you are trying to cast a node* into an int*
T->left=&p;
T->right=&p;
p->left=&q;

Creating BST from sorted array in C++

Can you help me understand why this code randomly results in memory access violation? Goal is to generate a binary search tree from sorted list.
Stepping through code I noticed a behavior where node pointer randomly changes when a recursive calls to fromSortedArray() function is returned. To give you a contex I am compiling this app using XCODE.
#include <iostream>
using namespace std;
class BST{
private:
struct Node {
int val;
struct Node *left, *right;
} *root;
public:
BST(){
this->root = NULL;
}
struct Node * fromSortedArray(int data[], int left, int right){
if(left>right) return NULL;
int m = left+(right -left)/2;
struct Node *node = (struct Node *) malloc(sizeof(struct Node*));
node->val = data[m];
node->left = this->fromSortedArray(data, left, m-1);
node->right = this->fromSortedArray(data, m+1, right);
return node;
}
void fromSortedArray(int data[], int n){
this->root = fromSortedArray(data, 0, n-1);
}
void deleteTree(struct Node *root){
if(root==NULL) return;
deleteTree(root->left);
deleteTree(root->right);
delete root;
}
void deleteTree(){
this->deleteTree(this->root);
}
void traverse(struct Node *root){
if(root == NULL) return;
if(root->left!=NULL)traverse(root->left);
printf("%d ", root->val);
if(root->right!=NULL)traverse(root->right);
}
void traverse(){
this->traverse(this->root);
}
~BST(){
deleteTree();
}
};
int main(int argc, char * argv[]){
BST tree;
int data[] = {2,3,5,6,7,9};
tree.fromSortedArray(data, 6);
tree.traverse();
cout << "\n";
return 0;
}
I think this line is wrong.
struct Node *node = (struct Node *) malloc(sizeof(struct Node *));
should be
sizeof(struct Node) becacuse you want to apply memory for Node not Node*
The Nodes are being malloced. One cannot combine malloc and delete. malloc must be matched with free and new must be matched with delete.
Avoid malloc. It gets you bytes of memory and nothing more, and you can easily miscalculate the number of bytes required. malloc should only be used in C++ in rare edge cases. More reading on the topic: In what cases do I use malloc vs new?
Use new instead of malloc and if at all possible, don't use new either. Use an Automatic variable, a library container, or a smart pointer instead.
This is a tree structure and, opinion here, so long as you observe the Rules of Three and Five you can get away with raw, stupid pointers because it's the the tree structure's job to handle the management of the nodes. That said, play around a bit with std::unique_ptr and std::make_unique when you get a chance. They can make your life easier.
Sticking with raw pointers for now, replace
struct Node *node = (struct Node *) malloc(sizeof(struct Node*));
with
Node *node = new Node;

c++ error: expected constructor, destructor, or type conversion before '*' token

Looked at every similar question on this compiler error. The following minimized code reproduces the error and I cannot see what the issue is. From reading here on SO, suspect it's the return type node* (being a struct) is invalid, but what else to specify as the return type? Thank you.
Header file:
#include<cstdio>
#include<cstdlib>
class double_clist {
struct node {
int info;
struct node *next;
struct node *prev;
};
node *start;
node *last;
int counter;
public:
node *create_node(int);
double_clist() {
start = NULL;
last = NULL;
}
};
Implementation File:
#include<cstdio>
#include<cstdlib>
node* double_clist::create_node(int value) { // Error on this line.
counter++;
struct node *temp;
temp = new(struct node);
temp->info = value;
temp->next = NULL;
temp->prev = NULL;
return temp;
}
When it reaches node here, it hasn't seen that it is inside double_clist yet. You need to also preface that with double_clist::.
double_clist::node* double_clist::create_node(int value) {

How do you allocate memory for an linked list when passing its reference instead of its pointer?

How do you allocate memory for an link list when passing its reference instead of its pointer?
For example:
struct node {
string info;
node *next;
};
void add(node &aNode){
//if I use
node *newNode;
newNode = new node;
aNode.next = newNode; //aNode.next = newNode; doesn't work either
//allocating on heap seems to give segmentation error.
}
int main() {
node *aNode;
aNode = new node;
add (aNode);
}
Compiler error: error: invalid initialization of reference of type ‘node&’ from expr
alternatively if I use
int main() {
node aNode;
add (aNode);
add (aNode);
aNode.next->next->info = "abc";
string a = aNode.next->next->info;
}
This give segmentation fault.
So is it possible to allocate for an linked list just with its reference? (this is C++)
It should be
node * newNode = new node;
aNode.next = newNode
You have to take care of deletion manually, e.g. check if aNode.next isn't already occupied (and delete if it is).
Further, the add function signature should read:
void add(node & aNode) { ... }
By the way, the STL comes with a nice <forward_list> ;-)
It's hard to tell what you're actually asking, but going by the question title perhaps you have in mind a node structure like this:
struct Node {
Node & next;
/* payload data */
Node(Node & n) : next(n) /* ... */ { }
};
Such a node would store its successor "by reference"; but you would have to initialize it with an existing node! (There is no such thing as a "null" reference.) By the Poultry-Oval Impasse, you cannot do this.
Alright, while you continue to refuse to post your full code, here is my almost literal copy/paste of your code which works fine with me:
Update: I'm adding a feature to add a node at the end, which you might want.
#include <string>
struct node {
std::string info;
node *next;
node(std::string i = "") : info(i), next(NULL) { }
};
void add(node &aNode)
{
node *newNode;
newNode = new node;
aNode.next = newNode;
}
void add_at_end(node &aNode, std::string value = "")
{
node *newNode, *n = &aNode;
while (n->next) n = n->next; // move to the end
newNode = new node(value);
n->next = newNode;
}
int main()
{
node aNode, bNode;
add(aNode);
add_at_end(bNode, "Hello");
add_at_end(bNode, "World");
add_at_end(bNode, "!");
}
Compile with g++ -o prog prog.cpp -W -Wall -pedantic.
Finally, here's the STL way of achieving the same thing:
#include <forward_list>
#include <string>
int main() {
std::forward_list<std::string> bList;
bList.push_front("Hello");
bList.push_front("World");
bList.push_front("!");
}
In your second variant of main(), you are calling add(aNode) twice. But you're providing it the same parameter each time. So although you're creating two new node objects, one of them is lost forever (a memory leak). And aNode.next ends up pointing to the other one. aNode.next->next is not a valid pointer, hence the seg-fault when you try to access something through it.
Depending on what you want to achieve, you could try this:
node aNode;
add(aNode); // Basically does: aNode.next = new node;
add(*aNode.next); // Basically does: aNode.next->next = new node;
There are better ways of doing linked-lists, but this would at least avoid the seg-fault.
Try
int main() {
node *aNode;
aNode = new node;
add (*aNode);
}
You have to pass reference to object, not a pointer.
I checked your code and I didn't get segmentation fault when allocating on stack: http://ideone.com/gTRIG.
My proposition:
#include <string>
using namespace std;
struct node {
string info;
node *next;
node(string str): info(str), next(NULL) {}
~node() { if(next != NULL) delete next; }
node *add(string info){
node *newNode = new node(info);
return aNode.next = newNode;
}
};
int main(){
node rootNode("My rootnode");
node *nxt = rootNode.add("Next node");
nxt->add("Last node");
// No need to call delete, because destructor will clear heap
}