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);
Related
I'm new to C++. I am initializing a class object Node in another class LCache. When I try to compile my code, I get the following error:
Line 22: Char 5: error: unknown type name 'left'
left -> next = right;
^
Below is the code I have written:
class Node{
public:
int k;
Node* prev;
Node* next;
Node (int key){
k=key;
prev=NULL;
next=NULL;
}
};
class LCache {
private:
Node* left = new Node(0);
Node* right = new Node(0);
left -> next = right;
right -> prev = left;
...
When I move left -> next = right; and right -> prev = left; inside a method in class LCache, the error goes away. Can you explain the reason here?
You can't perform non-declaration statements inside of a class declaration, like you are trying to do. You need to perform them inside of a class member function instead, or in this case inside of the class constructor (like you did with Node), eg:
class Node{
public:
int k;
Node* prev;
Node* next;
Node (int key){
k = key;
prev = NULL;
next = NULL;
}
};
class LCache {
private:
Node* left = new Node(0);
Node* right = new Node(0);
LCache() {
left->next = right;
right->prev = left;
}
~LCache() {
delete left;
delete right;
}
...
};
That being said:
NULL is deprecated in modern C++, use nullptr instead.
And you should use smart pointers whenever you have owned pointers that need freeing when they are done being used. Or better, just don't use objects dynamically when you don't actually need to.
Try something more like this instead:
class Node{
public:
int k;
Node* prev = nullptr;
Node* next = nullptr;
Node (int key) : k(key) {}
};
class LCache {
private:
std::unique_ptr<Node> left = std::make_unique<Node>(0);
std::unique_ptr<Node> right = std::make_unique<Node>(0);
LCache() {
left->next = right;
right->prev = left;
}
...
};
/* alternatively:
class LCache {
private:
Node left{0};
Node right{0};
LCache() {
left.next = &right;
right.prev = &left;
}
...
};
*/
You're trying to do an assignment in the declaration of the class type. That makes no sense!
You probably wanted to write things such as "assign to left's next field the value…" in some method of your code.
This far, this is plain invalid C++ – maybe go a little slower in your C++ intro. The step from "I write a C++ class and assign values to its fields" to "I build a graph" is non-negligible.
I'm trying to speed up a python routine by writing it in C++, then using it using ctypes or cython.
I'm brand new to c++. I'm using Microsoft Visual C++ Express as it's free.
I plan to implement an expression tree, and a method to evaluate it in postfix order.
The problem I run into right away is:
class Node {
char *cargo;
Node left;
Node right;
};
I can't declare left or right as Node types.
No, because the object would be infinitely large (because every Node has as members two other Node objects, which each have as members two other Node objects, which each... well, you get the point).
You can, however, have a pointer to the class type as a member variable:
class Node {
char *cargo;
Node* left; // I'm not a Node; I'm just a pointer to a Node
Node* right; // Same here
};
Just for completeness, note that a class can contain a static instance of itself:
class A
{
static A a;
};
This is because static members are not actually stored in the class instances, so there is no recursion.
No, but it can have a reference or a pointer to itself:
class Node
{
Node *pnode;
Node &rnode;
};
Use a pointer, & better initialized:
class Node {
char * cargo = nullptr;
Node * left = nullptr;
Node * right = nullptr;
};
Modern C++
It is a better practice to use smart-pointers (unique_ptr, shared_ptr, etc.), instead of memory allocations by 'new':
#include <string>
#include <memory> // For 'std::unique_ptr'
class Node {
public:
std::string cargo;
std::unique_ptr<Node> left;
std::unique_ptr<Node> right;
};
int main()
{
auto bt = std::make_unique<Node>();
(*bt).cargo = "Coffee";
(*bt).left = std::make_unique<Node>();
}
I'm working with this templated stack in C++:
Node:
template <typename TS>
struct spNodoPila {
TS info;
spNodoPila<TS>* next;
};
stack ADT struct with push and pop functions:
template <typename TS>
struct ADTPila {
spNodoPila <TS>* head = NULL;
spNodoPila <TS>* pos = NULL;
void push(TS dato) {
spNodoPila<TS>* nodo = new spNodoPila<TS>();
nodo->info = dato;
nodo->next = NULL;
if (head == NULL) {
head = nodo;
}
else {
nodo->next = head;
head = nodo;
}
}
void pop(spNodoPila<TS>*& nodo) {
nodo = new spNodoPila<TS>();
if (head == NULL) {
}
else if (head->next != NULL) {
nodo = head;
pos = head->next;
delete(head);
head = pos;
pos = NULL;
}
else {
nodo = head;
delete(head);
head = NULL;
}
}
};
and in this piece of code at the beggining of the previous struct i get the error "array type TS is not assignable" at the last line:
spNodoPila<TS>* nodo = new spNodoPila<TS>();
nodo->info = dato;
Something important to highlight is that later in the code i instance that stack as a str (char[60] typedef), because i want that stack to work with that type of data. Removing those instances of "str", the program compiles, so i guess there may be a problem allocating memory of char arrays, or in the way i'm doing something. Example of instance:
Stak template ADTPila instanced with "str" (char[60] typedef) into a list node:
struct spNodoLista {
sInfoLista info;
ADTPila <str> cand;
spNodoLista* prev;
spNodoLista* next;
spNodoVotos* vlink;
};
would appreciate your help!
For historical reasons, raw array types are consider4ed refence types.: They cannot be explicitly copied or assigned. But you can wrap your string in a struct as a workaround:
struct str{
char value[60];
};
or use std::array instead which essentially does the same with more convenience and ease:
#include <array>
using str= std::array<char,60>;
but do not change the base implementation of your template. You may want to specialize the template for raw array types or use traits to increase flexibility of the template, but that is a separate long story.
cheers,
FM.
like pointed in comment section, the problem was pretty simple: i was trying to assign directly a char array to another in "nodo->info = dato;", so i solved it with strcpy(dato->info,dato).
#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);
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
}