Segmentation Fault with declared variables C++ [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I am trying to create a node class. The node class has two variables: an int, and a pointer to another node. Here are my node constructors. I found on another stack overflow that in order to allocate memory for values, you need to include a "new ... " phrase.
Node::Node() {
next = new Node;
}
Node::Node(int new_num) {
num = new_num;
next = new Node;
}
I am using a method called AssignArray which takes an array of ints and turns that into a linked list of nodes. Parts of it work, except when I try to use the setNext method on my node. The setNext method is just a regular setter.
void Node::setNext(Node* new_next) {
next = new_next;
}
Node* Node::AssignArray(int list[], int i, int size) {
if (i == size) {
return NULL;
}
else {
Node new_node(list[i]);
i++;
new_node.setNext(new_node.AssignArray(list, i , size));
return &new_node;
}
}
Here is my main function so far:
int main() {
int nums1[] = {1,2,3,4,5};
int nums2[] = {1,3,5,7,9};
Node node1 = Node();
int nums1_size = sizeof(nums1)/sizeof(nums1[0]);
node1.AssignArray(nums1, 0, nums1_size);

The main issue is that you're calling setNext with the return value from AssignArray, which you return as &new_node, which is a pointer to a local Node that you allocated on the stack. As soon as the function returns, the stack unwinds and that Node instance ceases to exist, leaving the pointer dangling.
At the very least you should be doing:
Node* new_node = new Node(list[i]);
...
return new_node;
But I also feel like we're missing some things here. It would be nice to see the definition of Node. And how is this constructor not producing a stack overflow?
Node::Node() {
next = new Node;
}
In the constructor you do new Node which will call this same constructor again... which will call the constructor again...
Hmm.

I think new node added on constructor while infinite loop through itself.
Node::Node() {
next = new Node;
}
It will be better to avoid this type of calling.

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.

Passing a pointer as a private data member into a member function in Main [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm working on a problem for school where I am summing the values stored in a linear linked list.
I've got a struct that defines the node. It has a data portion and a pointer for next.
I have a class that has the functions that work on the list in the public section, and a pointer called head in the private section.
I've implemented a recursive function in my implementation file to sum values.
It takes a node* as its argument.
My question is, how do I pass that head pointer into the function in main() if it is a private data member?
I've successfully implemented this iteratively, so please assume that the list is instantiated successfully in main(). I just can't figure out how to pass a pointer into my function from there.
You don't pass it in. The class already owns it. If I may your class should look something like this:
class Foo {
node* _head;
node* _tail;
public:
Foo() : _head(nullptr), _tail(nullptr) {}
~Foo() {
while(_head != nullptr) {
node* temp = _head;
_head = _head->next;
delete temp;
}
}
void insert(const int arg) {
if(_head = _nullptr) {
_head = new node(arg);
_tail = _head;
} else {
_tail->next = new node(arg);
_tail = _tail->next;
}
}
int sum() const {
int total = 0;
for(auto i = _head; i != nullptr; i = i->next) {
total += i->val;
}
return total;
}
};
Note that sum has no need for _head to be passed to it because _head is in fact already a member of the object that sum is a method of.

Why did my C++mprogram stop working after being compiled? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm a computer science student and have been coding with Java for the past year. Now I'm interested in learning C++. The first program that I wanted to code with C++ is an implementation of stack using linked list, which I have coded before using java. I pretty much have no idea what I'm doing and basically just writing what I thought was right until I got no compile error. So I finally did it, my program got no compile error, but when I ran it, a pop-up appeared saying that my 'Stack.exe has stopped working'
Here's my code:`
#include <iostream>
using namespace std;
class Stack;
class Node;
class Node
{
public:
string element;
Node *next;
Node(string, Node);
};
Node::Node(string element, Node next)
{
this -> element = element;
*(this -> next) = next;
}
class Stack
{
private:
Node *tos;
public:
Stack()
{
tos = NULL;
}
void push(string str)
{
tos = new Node(str, *tos);
}
string peek()
{
return tos->element;
}
string pop()
{
string temp = tos->element;
tos = (tos->next);
return temp;
}
};
int main(void)
{
Stack bob;
bob.push("Wow");
bob.push("Wiw");
cout << bob.peek();
return 0;
}
Can someone tell me what I did wrong? I did it like this because this was how I did it with Java.
Thank you :D
You're dereferencing null or undefined pointers in a couple places. First let's look at your Node constructor:
*(this -> next) = next;
Since next hasn't been defined yet, dereferencing it leads to undefined behavior. In practice, next will point to some random place in memory that you probably don't own, so writing to it will cause a program crash. Your Node constructor should take a pointer to Node as its second parameter instead of taking a Node by value:
Node::Node(string element, Node* next)
: element{element},
next{next}
{}
Note that I've also initialized Node's members instead of default-initializing them and then assigning to them in the constructor's body.
After fixing Node's constructor, you'll also need to fix Stack::push to pass a pointer instead of an object:
void push(string str)
{
tos = new Node(str, tos);
}
Note that even after fixing the crashing problem, you'll still leak memory when you pop from your Stack (or when a Stack is destroyed). You need to delete anything you new, or better yet use std::shared_ptr<Node> instead of raw Node*s.

Data structure in List [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
template <class type> class list
{
private:
struct element
{
type data;
element* prev;
element* next;
};
element* begin;
element* end;
int size;
public:
list()
{
begin = NULL;
end = NULL;
size = 0;
}
// data is copied twice. (why? how to solve it?)
void add_at_beginning(type data)
{
element* temp = new element;
temp->next = NULL;
temp->prev = NULL;
temp->data = data;
if (size == 0)
{
begin = end = temp;
size++;
}
else
{
temp->next = begin;
begin->prev = temp;
begin = temp;
size++;
}
}
};
In the function called void add_at_beginning(type data) there is a problem, I wrote the problem in a comment.
Namely I don't understand what it means to say that data is copied twice, and most importantly how can I solve this problem so that nobody says that in this code data is copied twice.
Your function void add_at_beginning(type data) takes its data argument by value, this means that when you call the function, a copy of data is made.
Then when you assign temp->data = data;, a second copy is made.
That's why you've been told that in your code data is copied twice.
You can avoid one of those copies by taking your data argument by reference. This may result in some performance improvements if your class is used with large types.
If you change your function's prototype to :
void add_at_beginning(const type& data)
Then only one copy will be made.

[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;
}