Making a linked list from a premade file [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I'm trying to make a linked list from a premade file in c++. I'm struggling with the concept of taking the info if get from the file and using that to make the list. this is what i have so far.I also need to have the ability to insert and delete node from anywhere in the list.
struct node
{
string name;
int id;
float gpa;
node *next;
};
struct node* head;
void insertNodes(short id)
{
struct node* new_node = (struct node*) malloc(sizeof(struct node));
new_node->id = id;
new_node->next = head;
head = new_node;
}
void deleteNode() {
if (head == NULL){
cout << "List is empty" << endl;
return;
}
cout << head->id << " is removed." << endl;
head = head ->next;
}
int main() {
head = NULL;
node entry;
fstream datafile;
datafile.open("datafile.dat", ios::in | ios::binary);
if (!datafile)
{
cout << "Error!!\n";
return 0;
}
datafile.read(reinterpret_cast<char *>(&entry), sizeof(entry));
}

if you are doing this in C++ you shouldn't be using malloc and free generally, and the struct keyword before every instance of the struc; those are C-ism's. You should probably be creating a class of your own to represent the list and using member functions instead of a global variables head, and using new and delete for dynamic instantiation and destruction of variables. There are cases for malloc still but this does not appear to be one them.
additionally your insert function only seems to take an input value and add it to the tail of the list; generally in a list you will want to take the insertion point and value unless you are calling the method 'pushback' or something along those lines.
Further unless you rewrite to make a List class of your own you have not done any object oriented programming currently, as you are just doing things procedurally and the only thing c++ about this code is the use of iostream and fstream.
Suggest that you make node a class as well. it's mostly semantic but will get you in the habit, and give node a constructor even if you don't want to make accessors.
beyond that you are asking for information without having attempted anything and your question is too broad.

Related

Segmentation Fault with declared variables C++ [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 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.

What kind of code is this? C or C++ [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
I have written some code for my own practice purpose, but interesting thing happened. I was originally trying to write a C++ code, however I forgot include streamio library and using namespace std, then I just using printf() function all the way during my coding.
I think the most confusing part to me is I use .cpp extension and compile this program using VS 2015 compiler but I actually wrote in C style. Could someone tell me do I wrote a C or C++ code?
Here is the source code:
#include "stdafx.h"
#include <stdlib.h>
typedef struct node
{
int data;
node *next;
}node;
node *create()
{
int i = 0;
// Each variable must be assign to some value in the function
node *head, *p, *q = NULL;
int x = 0;
head = (node *)malloc(sizeof(node));
while (1)
{
printf("Please input the data: ");
scanf_s("%d", &x);
if (x == 0)
break;
p = (node *)malloc(sizeof(node));
p->data = x;
if (++i == 1) {
head->next = p;
}
else
{
q->next = p;
}
q = p;
}
q->next = NULL;
return head;
}
void printList(node head)
{
node *tmp = &head;
int counter = 0;
printf("Print out the list: \n");
while (tmp->next != NULL) {
tmp = tmp->next;
counter++;
//surprise to me printf() is pretty advance...
printf("%d item in the list: %d\n",counter, tmp->data);
}
}
int main()
{
printList(*create());
return 0;
}
Your code is, as far as I can tell, valid C++. It is not valid C, but could be made valid C with only a little effort.
C is nearly a subset of C++, but there is valid C code that is not valid C++ code -- and of course there's plenty of valid C++ code that's not valid C code.
The one thing that makes your code invalid as C is the use of the name node:
typedef struct node
{
int data;
node *next;
}node;
In C++, the struct node definition makes the type visible either as struct node or as node. In C, the struct definition by itself only creates the name struct node. The name node is not visible until the typedef is complete -- which it isn't at the point where you define node *next;.
If you rename your source file with a .c suffix and compile it as C, the compiler will complain that node is an unknown type name.

Template variable assignment segment fault 11 [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 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>;

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

Why can't i print binary tree? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I created a class binary search tree.
but the problem is when i print the tree it crashes.
i think it can be an endless recursion in function print().
Here is my code
struct node{
node *l,*r;
int data;
};
class BinTree
{
private: node *root;
public:
BinTree(){ root=NULL; }
void add(int a){ add_node(a,root); };
void add_node(int a, node *rot)
{ node *curr; curr=rot;
if(curr==NULL)
{
curr=new node;
curr->data=a;
curr->l=NULL;
curr->r=NULL;
return;
}
if(a>=curr->data) curr=curr->r,add_node(a,curr);
if(a<curr->data) curr=curr->l,add_node(a,curr);
}
void print(){ inorder(root); }
void inorder(node *curr)
{
if(curr->l!=NULL) inorder(curr->l);
cout<<curr->data<<" ";
if(curr->r!=NULL) inorder(curr->r);
}
};
Can anyone help me?
In your add_node method, you never actually assign a value to the root. It should be something like this:
if(curr==NULL)
{
curr=new node;
curr->data=a;
curr->l=NULL;
curr->r=NULL;
root = curr;
return;
}
But, for the future, I have the same advice as Basile - use your compiler and your debugger to your advantange.
Your add_node is broken. If curr is NULL, it creates a new node but it never actually adds it to the existing tree. Thus all additions you make are effectively ignored and the tree stays empty.
The inorder function dereferences curr without checking whether it is NULL, and print calls it without checking whether root is NULL. Thus, your crash most likely is caused by tryin to print out an empty tree and then dereferencing a null pointer.
Learn how to use a debugger. Enable all warnings in the compiler.
On Linux, this means compile with g++ -Wall -g and debug with gdb