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.
Related
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.
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;
}
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.
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 am currently working on a hash table project for school and i have run into an issue that i cant figure out. My professor provided us with classes that have functions that we need to implement and these functions make use of templates.
Anyway, in my insert function, i am running into an issue with setting a value of a node in the singly-linked list structure i am using to implement the hash table.
My problem is this:
void insert(U item1, U item2){ //For my project U is a string
Node<U>* temp = headPtr;
cout << item1 << endl; //Will print out the string no problem
//Assignment attempt
temp->SSN = item1; // causes a seg fault
temp->name = item2;
temp->next = NULL;
if(headPtr->next == NULL){
headPtr->next = temp;
size++;
}
else{
Node<U>* temp2 = headPtr;
while(temp2->next != NULL){
temp2 = temp2->next;
}
temp2->next = temp;
size++;
}
}
And it is quite frustrating because in previous assignments i have been able to use this insert function properly, the only reason it does not work i have concluded is because i must be missing something with templates that i have overlooked.
Also here is my node.h file:
#include <iostream>
using namespace std;
template <class T>
struct Node{
T SSN;
T name;
Node<T>* next;
};
I am trying to assign a string value to what SHOULD be a string value and should work to as far as my understanding goes but every time i run the program it gets to this point and there is just segment fault 11.
You have to replace
Node<U>* temp = headPtr;
with
Node<U>* temp = new Node<U>;
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
I have a push item function for a stack class. I wanted to check if *data had empty values, and if there is return an exception. The problem is I made the stack class for strings and later changed it so generic types can be used. Now *data->data() dont work for anyother types other than strings. So i wanted to check each *data type. So I added an If statement to check if the pointer Id looks like string.
So by doing this, I hoped that if(*data->data() will only execute for strings. But the problem is it checks for integers as well. I keep getting this error : error: member reference base type 'int' is not a structure or union.
How can fix this issue?
void push(Node<T> **head,T *data){
string s = typeid(*data).name();
if(s=="NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE"){
if(*data->data() == NULL){
throw NoDataException();
}
}
else{
if(s=="i"){
cout<<"here"<<endl;
}
}
Node<T> *temp = new Node<T>;
temp->data = data;
temp->next = *head;
*head = temp;
};
Use helper functions to do the check.
Add the following functions.
// A generic function for all types.
template <typename T> bool isEmpty(T const& t) { return false; }
// An overload for std::string.
bool isEmpty(std::string const& s) { return s.empty(); }
And then, replace:
string s = typeid(*data).name();
if(s=="NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE") {
if(*data->data() == NULL){
throw NoDataException();
}
}
else{
if(s=="i"){
cout<<"here"<<endl;
}
}
by
if ( isEmpty(*data) ) {
throw NoDataException();
} else {
// ...
}