I've tried to help a friend with a list code in c++. I've wrote:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
struct list* createlist(FILE *m);
struct list
{
char *data;
struct list *next;
}list;
main()
{
char a[100], ch;
struct list* obj;
cout<<"Enter the name of the file for obtaining input.."<<endl;
cin>>a;
FILE *in;
in=fopen(a,"r");
if(in!=NULL)
{
ch=fgetc(in);
if(ch=='1')
obj=createlist(in);
fclose(in);
}
return 0;
}
struct list* createlist(FILE *m)
{
cout<<"Entered createlist function..!"<<endl;
char *tempStr = (char *)malloc(30 * sizeof(char));
struct list *curr, *head = (struct list *)malloc(sizeof(struct list));
curr = head;
curr->data = tempStr;
char c;
int i=0;
curr=NULL;
while(EOF!=(c=fgetc(m)))
{
if((c==' ') || (c=='\0') || i == 29)
{
if(i==0)
{
continue;
}
tempStr[i]='\0';
i=0;
struct list *temp = curr;
curr = (struct list *)malloc(sizeof(struct list));
temp->next = curr;
tempStr = (char *)malloc(30 * sizeof(char));
curr->data = tempStr;
continue;
}
tempStr[i]=c;
i++;
}
return head;
}
But the code throw exception. I tried to understand what went wrong and change the code for 2-3 hours, and could not understand. I'm allocating space for the list item, but when I try to assign value to next at the line
temp->next = curr;
I get segmentation fault.
At the end I've managed to solve it by taking some code from the net instead of mine:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
struct list* createlist(FILE *m);
struct list
{
char *data;
struct list *next;
}list;
main()
{
char a[100], ch;
struct list* obj;
cout<<"Enter the name of the file for obtaining input.."<<endl;
cin>>a;
FILE *in;
in=fopen(a,"r");
if(in!=NULL)
{
ch=fgetc(in);
if(ch=='1')
obj=createlist(in);
fclose(in);
}
return 0;
}
struct list* createlist(FILE *m)
{
cout<<"Entered createlist function..!"<<endl;
char *tempStr = (char *)malloc(30 * sizeof(char));
struct list *curr, *head = (struct list *)malloc(sizeof(struct list));
curr = head;
curr->data = tempStr;
char c;
int i=0;
curr=NULL;
while(EOF!=(c=fgetc(m)))
{
if((c==' ') || (c=='\0') || i == 29)
{
if(i==0)
{
continue;
}
tempStr[i]='\0';
i=0;
struct list *temp = curr;
curr = (struct list *)malloc(sizeof(struct list));
temp->next = curr;
tempStr = (char *)malloc(30 * sizeof(char));
curr->data = tempStr;
continue;
}
tempStr[i]=c;
i++;
}
return head;
}
But I still don't know what went wrong in my code. Can anyone help me understand so I won't repeat my mistake in the future?
The two versions are identical as far as I can see, but the error is easy to tell. Here's your code with some comments
// at this point curr is NULL (see start of while loop)
struct list *temp = curr;
// so now temp is NULL
curr = (struct list *)malloc(sizeof(struct list));
// now curr is pointing at some memory, but temp is still NULL
temp->next = curr;
// temp is NULL so this crashes
Like everyone else I think if you remove curr = NULL; you'll be closer.
Your 'temp' is NULL:
curr=NULL;
Afterwards:
struct list *temp = curr;
And finally:
temp->next = curr;
You are trying to use structure pointer that has a NULL value.
I know this is not going to help you much, but I see several other problems with the code and it's not easy to read.
Since you marked this C++, did you considet using one of the std containers? Like std::list ?
Before the while loop, you are assigning NULL into curr
curr=NULL;
Then, you are assigning curr to temp
struct list *temp = curr;
Then when you do
temp->next = curr;
you get a segmentation fault because NULL does not have a next pointer.
If you remove curr=NULL;, you should be ok.
the problem is the you do
curr=NULL;
just before he while loop
Related
I'm trying to transition from an almost entirely Java background to getting comfortable with C++. I'm practicing by trying to build a basic Linked List.
#include <iostream>
#include <string>
using namespace std;
struct node
{
string data;
node *next = NULL;
};
class linkedlist
{
public:
node *head;
public:
linkedlist()
{
head = NULL;
}
void addNode(string s)
{
node *newNode = new node;
newNode->data = s;
if(head == NULL)
head = newNode;
else
{
node *temp = head->next;
while(temp != NULL)
temp = temp->next;
temp = newNode;
}
}
void printList()
{
node *temp = head;
while(temp != NULL)
{
cout << temp->data << '\n';
temp = temp->next;
}
}
};
The issue at hand is that once I add a new node using void addNode(string s), it does not appear when I attempt to print the list (starting from the head) with void printList().
For example:
int main(int argc, const char * argv[])
{
int n;
string str;
linkedlist list;
cout << "Please enter the number of strings you'd like to enter:\n";
cin >> n;
for(int i = 0;i < n;i++)
{
string temp;
cout << "Enter string #" << i + 1 << '\n';
cin >> temp;
list.addNode(temp);
}
cout << "This is your linked list: ";
list.printList();
return 0;
}
Using main() above, my results become:
This is your linked list:
(string 1)
I'm pretty certain I'm using pointers improperly here but I don't see why. I've done as much digging as I can on my own for some clarification on how I could be doing this wrong but I'm coming up blank.
Thanks for any clarification you folks can provide.
The problem is here:
node *temp = head->next;
while(temp != NULL)
temp = temp->next;
temp = newNode;
You're traversing the list, then setting temp to the value of the newNode. When temp goes out of scope, the value for newNode isn't stored anyplace.
What you want to do is set the next pointer of the last node to the value of newNode, i.e.
node *temp = head;
while(temp->next != NULL)
temp = temp->next;
temp->next = newNode;
The code above traverses the list until it finds a node that doesn't have a next node, and sets its next node to the newNode, thus adding it to the list.
I want to read a text file and store new words in linked list. From this linked list I want to write a dictionary file with new words. I don't know why my code don't run. Can anyone help me?
p/s: when i run debug it found this when store vector element to new_node->word
Error
This is my code
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <sstream>
#include <cstring>
using namespace std;
typedef struct dictionary
{ string word;
int line;
int page;
struct dictionary* next;
} node;
int main()
{
node* Head = NULL;
ifstream file("filetest.txt");
if(file.fail())
cout << "Loi mo file! "<<endl;
string temp;
int cpage = 1,cline = 1;
while(getline(file,temp))
{
stringstream spliter;
spliter << temp;
vector<string> result;
while(!spliter.eof())
{
string str;
spliter >> str;
result.push_back(str);
}
for(size_t i = 0;i != result.size();i++)
{
if(Find(Head,result[i])==0)
{
Append(&Head,result[i],cline,cpage);
}
}
cline++;
if(cline == 25)
cpage++;
}
file.close();
;
ofstream outfile("test.txt");
node* p = Head;
while(p != NULL)
{
outfile << p->word <<","<<p->page<<"-"<<p->line<<endl;
p=p->next;
}
}
Append( add member to linked list)
void Append(node** First,string &newstr,int newl,int newp)
{
node* new_node = (node*)malloc(sizeof(node));
node* last = *First;
new_node->word=newstr;
new_node->line=newl;
new_node->page=newp;
new_node->next = 0;
if(*First == 0)
{
*First = new_node;
return;
}
while(last->next != 0)
{
last = last->next;
}
last->next = new_node;
return;
}
Find( check if a word is new or not)
int Find(node* head,string &tumoi)
{
node* current = head;
while(current != 0)
{
if(current->word == tumoi)
return 1;
current = current->next;
}
return 0;
}
You should not use malloc with C++ types. It does not properly initialize them.
Your node struct contains a std::string which needs to have its constructor called to be properly initialized.
When you do this
node* new_node = (node*)malloc(sizeof(node));
new_node->word=newstr;
The new_node->word is not initialized and can contain pointers to nowhere.
You should do
node* new_node = new node();
new_node->word=newstr;
instead.
I am trying to implement Linked List. In this sample program, user inputs an integer value (the number of strings to store in the list) and then strings one by one... But after several inputs (may be 4 or 5) the program crashes like the image here...
Even, I can't call any function more than 3 times at once which contains malloc() inside them..
I don't know why the problem is occurring. Help me fixing the issue....
#include <bits/stdc++.h>
using namespace std;
typedef struct Linked_List NODE;
struct Linked_List
{
string data;
NODE* next;
};
//Function prototypes
NODE *traverse(NODE *temp);
NODE* createNode(string data);
void preAppend(NODE* ln_list, string x);
NODE* find_data(NODE* ln_list, string data);
int main()
{
NODE* x=createNode("");
int t;
cin >>t;
string z;
while(t--)
{
cin >> z;
preAppend(x, z);
}
traverse(x);
return 0;
}
NODE *traverse(NODE *temp)
{
cout << temp->data << endl;
if(temp->next==NULL) return temp;
traverse(temp->next);
}
NODE* createNode(string data)
{
NODE* node = (NODE*)malloc(sizeof(NODE));
if(node==NULL)
{
printf("Error creating node (Error! Allocating Memory)\n");
exit(1);
}
node->data = data;
node->next = NULL;
}
void preAppend(NODE* ln_list, string x)
{
NODE* new_node = (NODE*)malloc(sizeof(NODE));
if(new_node==NULL)
{
printf("Error! Appending (Error Allocating Memory)\n");
exit(1);
}
new_node->data = x;
new_node->next = ln_list->next;
ln_list->next = new_node;
}
NODE* find_data(NODE* ln_list, string data)
{
NODE* current_node;
current_node = ln_list;
while(current_node->next!=NULL)
{
if(current_node->data == data)
{
return current_node;
}
current_node = current_node -> next ;
}
return NULL;
}
There are several problems in your code:
Usage of malloc instead of new
Using malloc for objects containing c++ objects (like stringin your case) won't call the constructors and therefore any operation upon the non constructed objects will fail.
If your program works without the return statements, it's because of undefined behaviour
Solution:
Replace
NODE* new_node = (NODE*)malloc(sizeof(NODE));
with
NODE* new_node = new NODE;
No return statements in non void functions
NODE *traverse(NODE *temp)
{
cout << temp->data << endl;
if (temp->next == NULL) return temp;
return traverse(temp->next); // return statement is needed here
}
NODE* createNode(string data)
{
NODE* node = new NODE;
if (node == NULL)
{
printf("Error creating node (Error! Allocating Memory)\n");
exit(1);
}
node->data = data;
node->next = NULL;
return node; // return statement needed here
}
Abuse of recursion
Using recursion in traverse may result in a stack overflow for long lists.
You should use a iterative approach. But you've found out that one already.
I uploaded the whole code at once. This method should work without any interruption
although if you want a complete understanding of each part i will recommend you to go over this article that i wrote on my website.
https://www.thebytewise.com/post/data-structure-and-algorithm-using-c-linear-linked-list-thebytewise
#include<stdio.h>
#include<stdlib.h>
void createList();
void traverseList();
struct node{
int data;
struct node *next;
}*header;
int main(){
int n;
printf("Enter the number of elements: ");
scanf("%d", &n);
createList(n);
printf("\nData in the list:\n");
traverseList(n);
return 0;
}
void createList(int n){
struct node *newNode, *temp;
int data, i;
newNode = (struct node *) malloc(sizeof(struct node));
if(newNode == NULL){
printf("ERROR: Memory Overflow");
}
else{
printf("Enter element 1: ");
scanf("%d", &data);
newNode->data = data;
newNode->next = NULL;
header = newNode;
temp = newNode;
for(i=2;i<=n;++i){
newNode = (struct node *) malloc(sizeof(struct node));
if(newNode == NULL){
printf("ERROR: Memory Overflow");
}
else{
printf("Enter element %d: ",i);
scanf("%d",&data);
newNode->data = data;
newNode->next = NULL;
temp->next = newNode;
temp = temp->next;
}
}
}
}
void traverseList(int n){
struct node *temp;
int i;
if(header == NULL){
printf("ERROR: Memory Underflow");
}
else{
temp = header;
for(i=0;i<n;++i){
printf("\ndata %d= %d",i+1, temp->data);
temp = temp->next;
}
}
}
I'm trying to implement insertion sort with link list in C++. But, whenever I'm trying to assign pointer to new node to a link, it gives "segmentation fault (core dumped)". I've checked the line "(*head)->next = newNode;" gives this error.
To run the program compile the program and for input copy the two lines inside comment before the start of insertionSort.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
class Node
{
public:
int num;
Node *prev;
Node *next;
Node(int input);
};
Node::Node(int input)
{
num = input;
prev = NULL;
next = NULL;
}
/*
5 2
1 5 3 4 2
*/
void insertionSort(Node **head, int newInput)
{
Node* newNode = new Node(newInput);
if (*head == NULL)
{
*head = newNode;
}
else
{
Node *itr = *head;
if (itr->num >= newInput)
{
newNode->next = itr->next;
itr->prev = newNode;
*head = itr;
}
else
{
Node *itr = (*head)->next;
while (itr != NULL)
{
if (itr->num >= newInput)
{
newNode->prev = itr->prev;
newNode->next = itr;
itr->prev = newNode;
newNode->prev->next = newNode;
newNode = NULL;
}
itr = itr->next;
}
if (newNode != NULL)
{
if (itr == NULL) {
(*head)->next = newNode;
}
else
itr->next = newNode;
}
}
}
}
void printList(Node *head)
{
Node *itr = head;
while (itr != NULL)
{
cout << itr->num << " ";
itr = itr->next;
}
cout << endl;
}
int main()
{
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int n, k;
cin >> n >> k;
Node *head = NULL;
int num, i = -1;
while (++i < n)
{
cin >> num;
insertionSort(&head, num);
}
printList(head);
return 0;
}
Try changing
itr->prev = newNode;
to
newNode->prev = newNode;
I'm running your code, and get a write access violation. "newNode->prev was nullptr"
You seemed got your variables mixed up in line 53:
newNode->prev->next = newNode;
should be:
its->prev->next = newNode;
And it has to be executed before its->prev is overwritten. But then the code is still not functioning as you want it. You have put some more effort into it. Within the while-loop, you set newNode to NULL and then reiterate.
And you should really comment your code. You understand your own mistakes better when you describe what you are doing.
By the way, did you notice that you mask Node* itr from line 36 at line 45? you could just reuse the existing object, as you don't use it anymore.
I am new on data structure. I am trying to write a linked list for a string and display the list to screen. It crash at Node *p = create("I "); with the warning of access violation writing location. Here is my code, I don't know how to fix it. Please help. Thank you very much.
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
struct Node
{
string data;
Node *prev, *next;
};
Node* create (string value)
{
Node *temp = (Node*)malloc(sizeof(Node));
if (NULL==temp) return NULL;
temp->data=value;
temp->next=NULL;
temp->prev=NULL;
return temp;
}
void addHead (Node* head, string value)
{
Node *temp = new Node;
temp->data=value;
temp->next=head;
head->prev=temp;
head = temp;
temp->prev = NULL;
}
void addTail (Node* head, string value)
{
Node* s = new Node;
Node* temp = new Node;
s=head;
while (s->next!=NULL)
s = s->next;
s->next = temp;
temp->prev = s;
}
void display (Node* head)
{
if (head==NULL) return;
else
{
cout << head->data << " ";
display (head->next);
}
}
int main()
{
Node *p = create("I ");
addTail(p, "want ");
addTail(p, "cookies ");
display(p);
return 0;
}
You need to create a Node using new, not malloc, in your create function. Using malloc, the constructor for Node is not called, and the assignment to data will access an uninitialized string object.