Struct allocated with malloc, why? C++ code analysis [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
The line:
struct Node* newNode = (struct Node*) malloc(sizeof(struct Node));
Why does the new struct being instantiated involve malloc (allocating the blocks of memory for the size of the struct) ?
Also, is the re-declaration of struct redundant?
Wouldn't the following accomplish the same task?
Node* newNode = new Node;
MODE CODE BELOW:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* next;
};
struct List
{
struct Node *head; // pointer to head node of list
};
//creates a new list Node
struct Node* newListNode(int data)
{
struct Node* newNode =
(struct Node*) malloc(sizeof(struct Node));
newNode->dest = dest;
newNode->next = NULL;
return newNode;
}

You asked
Wouldn't Node* newNode = new Node; accomplish the same task?
No, this is not equivalent in some very important ways. If part of the interface (contract) of this function is that it returns a pointer that can be passed to free(), then implementing it with new would violate that contract.
Additionally, the repeated redundant use of the struct keyword suggests that an effort has been made to ensure this code compiles correctly both as plain C and as C++.

Related

How to delete the root node in a 1-layer BST [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have a simple BST node struct:
struct Node {
int value;
Node* left;
Node* right;
}
Back in C, the constructor would be like:
Node* construct_node(int value){
Node* node = (Node*) malloc(sizeof(Node));
node->data = value;
node->right = NULL;
node->left = NULL;
}
Making it is easy to delete the root, since it is just another dynamically allocated node.
In C++, however, the constructor doesn't return anything, and the root is the only node that is statically allocated.
Node::Node(const int& value, Node* left, Node* right) {
this->value = value;
this->left = left;
this->right = right;
}
Is there any way to go around this so that deleting the root is possible just like in C, even if the user declares it statically in the main? Or a way to strict the user to declare it only using 'new'? Keeping it 1-layer without adding another class as the tree holding nodes by pointing to the root one.
You can simply not define a constructor of this type at all. Just create a default constructor,
Node::Node(){}
And make all members private with getters. This will make this constructor useless.
Now create a function which behaves just like the one in C,
Node* Node::new_node(int val, Node *l, Node *r){
Node *n = new Node();
n->left = l;
n->right = r;
return n;
}
This will force people to use this constructor only.
Okay, I think you have some confusion about pointers between C and C++. They're the same thing. There's nothing at all that keeps you from writing this method in C++:
Node * construct_node(int value) {
Node * node = new Node(value, nullptr, nullptr);
return node;
}
At which point, all that really changes in deleting the node is that you use:
delete node;
Instead of:
free(node);
Everything else remains the same. Now, you have to decide what happens when you delete a Node. Do you want destructor that deletes the left and right nodes recursively? Or do you let them potentially get lost? So you're not done.

What does "Warning : No return statement in function returning non-void" mean? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
This function creates a new node for a circular linked list,as shown:
Node *newNode(int data)
{
Node *temp = new Node;
temp->next = temp;
temp->data = data;
}
However, I am getting a warning from the compiler. I know it should have a return value but am not sure of the correct way to implement it. I'd be grateful for any help regarding this.
As defined by
Node *newNode(int data)
your function is expected to return a Node pointer. However your implementation has no such return. The compiler warns you about this problem. A priori you can fix the problem by:
Node *newNode(int data)
{
Node *temp = new Node;
temp->next = temp;
temp->data = data;
return temp;
}
Note: this is quite a serious problem and you must fix your code, otherwise you have an undefined behavior.
Node *newNode(int data) means this function has to return a Node*, which it doesn't, and that causes undefined behavior. What you probably meant to do is adding return temp at the end of the function. Otherwise you leak memory anyway.
Fix:
Node *newNode(int data)
{
Node *temp = new Node;
temp->next = temp;
temp->data = data;
return temp;
}
To actually fix this function, consider using smart pointers, so someone definitely and explicitly owns the heap-allocated object:
#include <memory>
struct Node {
Node* next;
int data;
};
[[nodiscard]] auto newNode(int const data) {
auto temp = std::make_unique<Node>();
temp->next = temp.get();
temp->data = data;
return temp;
}

Can't assign a new object to pointer pointer type in cpp [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Assigning a new object to a pointer pointer type in cpp crushes the program.
Code looks like this:
#include <iostream>
using namespace std;
struct Node{
int key;
Node * nex;
};
int main(){
Node * my_node = new Node;
Node ** pp_node;
*pp_node = my_node;
return 0;
}
I think that the issue here is following: pp_node is null and by typing *pp_node = my_node; I am trying to dereference null but the question is how can I assign my_node to the pointer, pp_node is pointing at?
pp_node should contain the address of my_node , in order to have pp_node point at my_node(which is itself a pointer and holding an address).
#include <iostream>
struct Node{
int key_;
Node * nex;
};
int main(){
Node node={34, nullptr};
Node* p_my_node = &node;
Node** pp_node;
pp_node = &p_my_node;
std::cout<<(**pp_node).key_;
return 0;
}
Now
p_my_nodeis a piece of memory whose value(data it is holding) is address of node. So it points at node
pp_node is a piece of memory whose value is address of p_my_node, So it points at p_my_node
the output of the code above is 34, as we expected.
pp_node is uninitialized. You need to initialize it first.
Node** pp_node = new Node*;
*pp_node = my_node;

[c++]The importance of dynamic allocation [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
I wrote a doubly linked list, and trying to add an append()(insert at the end)and len()(caculate the number of member in the list). I just don't understand why it doesn't work now. Here is the simplest code:
#include<iostream>
using namespace std;
class linkedList{
private:
struct node{
node* last;
node* next;
char* str;
};
node sentinel;
public:
linkedList();
~linkedList();
int len();
void append(char*);
};
linkedList::linkedList(){
sentinel.last=&sentinel;
sentinel.next=&sentinel;
sentinel.str="I am sentinel!!";
};
linkedList::~linkedList(){};
int linkedList::len(){
node* currentNode=&sentinel;
int count=0;
while ((*currentNode).next!=&sentinel){
count++;
currentNode=(*currentNode).next;
cout<<(*currentNode).str<<endl;
}
return count;
}
void linkedList::append(char* str){
node newNode;
newNode.str=str;
newNode.last=sentinel.last;
(*sentinel.last).next=&newNode;
sentinel.last=&newNode;
newNode.next=&sentinel;
}
int main(){
linkedList myList;
myList.append("Hello");
myList.append("World");
int length=myList.len();
cout<<length<<endl;
return 0;
}
What I am doing is just add two new nodes into the linked list, and caculate the total number of my nodes. it should return 2. but why it doesn't work?
newNode in your code below will go out of scope as soon as append is finished executing. Assigning it's memory address as a pointer to more global member is likely going to end in a segfault.
void linkedList::append(char* str){
node newNode;
newNode.str=str;
newNode.last=sentinel.last;
(*sentinel.last).next=&newNode;
sentinel.last=&newNode;
newNode.next=&sentinel;
}
Try allocating your node on the heap using new node, possibly using a shared_ptr to make memory management a bit simpler.
void linkedList::append(char* str){
node *newNode = new node;
newNode->str=str;
newNode->last=sentinel.last;
(*sentinel.last).next=newNode;
sentinel.last=newNode;
newNode->next=&sentinel;
}
With this approach, be sure to cleanup the nodes when destructing your linkedlist, via the delete operator on each node.
Alternatively, look into using shared_ptr's to a Node instead of raw pointers, which will always call delete when the linkedlist (and nobody else) is pointing to the node.
Use the new keyword to allocate a new node:
void linkedList::append(char* str){
node *newNode = new node();
newNode->str=str;
newNode->last=sentinel.last;
(*sentinel.last).next=newNode;
sentinel.last=newNode;
newNode->next=&sentinel;
}

Am I add the item in front of linked-list correctly [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
In this case, I need to implement addFront() method which is to keep adding a integer in front of a linked-list.
class Node{
public:
int data;
Node* next;
Node* prev;
}
class List {
void addFront(int item);
protected:
Node* dummyNode;
int numItems; //number of item is the linkedlist
};
Below is what I tend to implement addFront():
void addFront(int data){
Node* head = new Node();
if(numItems == 0) //if no item in the list.
{
//Set the head node to be dummyNode
head = dummyNode;
//Because the next node the head is pointing to is NULL.
head -> next = NULL;
}
//Create a new node.
Node* newNode = new Node();
//Set value
newNode->data = data;
//Let the previous pointer of dummyNode points to newNode.
head->prev = newNode;
//Re-set head to be newNode.
head = newNode;
numItems++;
}
Am I doing correctly? If not, why? If yes, is there any better way to do this?
I won't go into too many details as this appears to be a homework assignment, but the short answer is, no.
Node* head = new Node();
if(numItems == 0) //if no item in the list.
{
//Set the head node to be dummyNode
head = dummyNode;
//...
}
You have a memory leak in the code above.
First of all name dummyNode which denotes the beginning of the list looks strange. It would be much better to substitute it for head. Also you need a variable that will point to the tail of the list.
As for your function then it is simple
void addFront( int data )
{
Node *head = new Node();
head->data = data;
head->next = dummyNode;
dummyNode->prev = head;
dummyNode = head;
numItems++;
}
Also it would be not bad if class Node had a constructor with parameters that to accept data and pointers. Class list also has to have an explicitly defined default constructor or its data members have to be initialized when they are defined.