This is my sample C++ code for a linked list . This is not actually a linked list but just a dummy program. I get unexpected output for this program.
#include<iostream>
using namespace std;
struct list{
int data;
list *next;
};
void setData(list ob){
int d;
cout<<"enter data"<<endl;
cin>>d;
ob.data=d;
}
void getData(list ob){
cout<<"Data is :"<<ob.data<<endl;
}
int main(){
list node1,node2,node3;
setData(node1);
setData(node2);
setData(node2);
getData(node1);
getData(node2);
getData(node3);
return 0;
}
My input for the code was 2,3 and 4. The unexpected output that I get is -
enter data
2
enter data
3
enter data
4
Data is :2293540
Data is :4201920
Data is :2293608
Edit
struct list{
char data; list next;
}
void main(){
list *start,node1,node2;
//I got stuck on the below two lines
start=(struct list)malloc(sizeof(list)); //Dynamic allocation of memory of size list whose address is stored in start
start=&node1; // start holds the address of node1 which is not dynamically allocated .
I don't understand why is *start given a dynamic address if the second statement overrides it by giving it the memory address of node1 which is in the stack(atlest what I understood).
Because you are passing your linked list by value. To change this, pass by reference.
void setData(list& ob){
int d;
cout<<"enter data"<<endl;
cin>>d;
ob.data=d;
When you pass by value, C++ makes a copy of whatever you pass in. So when you are calling getData, you pass in a copy of a list that has no data in it, so garbage is getting printed.
You need to pass in your list by reference
void setData(list& ob){
int d;
cout<<"enter data"<<endl;
cin>>d;
ob.data=d;
}
You are currently passing in ob by value, so although you are indeed setting the data attribute correctly, you are doing so to the function-local copy of ob, not the original list that you passed into the function.
Related
I'm having trouble understanding Linked Lists. I am trying to print to standard output all the items in the list, but only the last record is being printed out. I am not sure what is wrong with my code. I believe the head pointer is only storing one record and is being overwritten each time I put data into a new record, but I don't know where the issue lies exactly and I'm not sure how to rectify it because I can't see where the code is wrong. Please let me know if you can see the issue with my code, and how I can fix it. Thank you.
My int main function is small, but I believe all the necessary information is there. Here is my int main:
int main(void){
sPtr head;
head=NULL;
cout<<putIntoList(head);
system("pause");
return 0;
}
The struct looks like this:
struct drugData{
string name;
string disease;
int effectiveness;
drugData *next;
drugData(){
effectiveness=0;
name="n";
disease="n";
next=NULL;
}
}
And here is the typedef to use for drugData types as function parameters.
typedef drugData* sPtr;
This is the first function, which reads data from a file into the fields of the struct drugData.
void putIntoList(sPtr &head){
(code to open file is located here)
sPtr structPointer=new drugData;
while (!inFile.eof()){
getline(inFile,tempDrugName, ',');
getline(inFile,tempDisease,',');
inFile>>tempEff;
structPointer->name=tempDrugName;
structPointer->disease=tempDisease;
structPointer->effectiveness=tempEff;
cout<<"Drug:"<<structPointer->name;
approvalGetter(structPointer);//This function asks the user for input on each drug.
}
headInsert(structPointer, head);//This function inserts new objects at head.
menuOptions(structPointer, head);//This function presents a menu to either print, search, or quit.
inFile.close();
}//End of putIntoList function.
Here is the code for the function called headInsert:
void headInsert(sPtr &newItem, sPtr& head){
newItem->next=head;
head=newItem;
newItem=NULL;
}
And here is the code for the menuOptions function:
void menuOptions(sPtr& pointer, sPtr& head){
int menuAnswer=0;
cout"Choose a menu option:"<<endl<<"(1) Print"<<endl<<"(2) Search"<<endl<<"(3) Quit"<<endl;
cin>>menuAnswer;
if (menuAnswer==1){
for (pointer=head; pointer!=NULL; pointer=pointer->next){
cout<<pointer->drugName;
}
}//Included here is the menu options 2 and 3.
}
I expect the output to be the names of the drugs contained in the file, of which there are six, but the only output I see is the name of the last drug in the file.
i am passing a struct by reference to one function of a class treestr and storing it there in a vector.
Then passing the same struct by reference to another function and performing some computation on data member of struct. This data member gets updated in the original struct but not in the ones stored in the vector.
(Sorry for any mistakes, new to c++, new to stack overflow). Please help.
//Structure description
Struct point{
int x;
int y;
int cal{0};
};
Struct node{
point p;
int data; //value to be updated by func
};
int main(){
treestr * tree= new treestr(); //create object
int i=0,n=100;
vector<node> nob;
while(i<=n){
p={1,5}; //some values input by user
node n={p,i};
nob.push_back(n)//storing the struct node objects seperately in a
//vector
treestr->insert(n); //inserting into tree class
i++;
}
//calling func to do some computation on the struct objects inserted
for(i=0;i<n;i++){
int x=tree->func(nob[i]);
cout<<x.cal; //getting updated values from the function
}
for(i=0;i<N;i++){
tree->func2(nob[i]);
}
return 0;
}
//class description
class treestr{
vector<node> buck;
insert(node& n){
buck.push_back(n);
//store nodes
}
func(node& n){
//calculations
return n.cal; Value got updated in main.
}
func2(node &n){
int val1=n.cal; //this assigns updated value
int val2=buck[i].p.cal; //this assigns 0(default value)
if(val1==val2){ //never matches, val2 is 0 for all objects, val1 is
//not after getting updated
//do something
}
}
};
The cal gets updated in the main function but not in the class where I have stored. Please ignore grammatical and syntactical mistakes, the code returns correct output however this is something that I need to improve my code.
Any possible reasons??
Try changing
node n={1,5,0}
to
node * n;
node -> x = 1;
node -> y = 5;
node -> cal = 0;
From what I know of pointers you need to assign each value individually.
Also
tree->insert(n)
needs to be
tree.insert(n)
Another thing
int node.cal=tree->func(n);
Not sure what this is supposed to do, but I know it won't work. 'int' needs to be before a variable name. When accessing cal from node your call needs to be an -> and when accessing func from tree it needs to be a .
I am learning data structures in C++. This is a simple program for insertion
using links and nodes. The insertion takes place at the beginning of the node.
I do not understand some parts of the code.
In the function display() the pointer np points to the inserted info and then takes the value of the previous info using the next node. The next pointer is pointing to the previous info using the insert_beginning() function.
Displaying is done using the while loop. How does the next pointer change its value during each loop?
PS: The program runs fine.
#include<iostream>
#include<process.h>
#include<cstdlib>
using namespace std;
struct node
{
int info;
node *next;
}*start,*newptr,*save,*ptr;
node *create_new_node(int);
void insert_beg(node*);
void display(node*);
/*----------------------------------------------------------------------------------------------------------------------------
The pointer 'start' points to the beginning of the list.
Function 'create_new_node()' takes one integer argument , allocates memory to create new node and returns
the pointer to the new node.(return type: node*)
Function 'insert_beg()' takes node* type pointer as an argument and inserts this node in the beginning of the list.
Function display takes node* type pointer as an argument and displays the list from this pointer till the end of the list
------------------------------------------------------------------------------------------------------------------------------
*/
int main()
{
start=NULL;
int inf;
char ch='y';
while(ch=='y'||ch=='Y')
{
system("cls");
cout<<"enter information for the new node ";
cin>>inf;
cout<<"\ncreating new node. Press enter to continue ";
system("pause");
newptr = create_new_node(inf);
if(newptr!=NULL)
{
cout<<"\nnew node created successfully. Press enter to
continue. ";
system("pause");
}
else
{
cout<<"\nCannot create new node. ABORTING!! ";
exit(1);
}
cout<<"\nnow inserting this node in the beginning of the list.
Press enter to continue ";
system("pause");
insert_beg(newptr);
cout<<"\nNow the list is \n";
display(start);
cout<<"\nPress 'Y' to enter more nodes, 'N' to exit\n";
cin>>ch;
}
return 0;
}
node *create_new_node(int n)
{
ptr=new node;
ptr->info=n;
ptr->next=NULL;
}
void insert_beg(node *np)
{
if(start==NULL)
start=np;
else
{
save=start;
start=np;
np->next=save;
}
}
void display(node *np)
{
while(np!=NULL)
{
cout<<np->info<<" ->";
np=np->next;
}
cout<<"!!!\n";
}
To cut the long story short - per my understanding, your basic question is:-
display is done using the while loop. how does the next pointer change
its value during each loop??
This happens precisely in this line:-
np=np->next;
You are basically advancing the pointer to the node structure to another node structure whose address is in next member of the first node structure. This is text book stuff and any basic algo book should cover this thoroughly
HTH!
Your question is somewhat unclear. Especially because you state that:
PS:the program runs fine.
which it for sure does not. There is a bug that simply means this program will not work.
The problem is that create_new_node is not returning the pointer value
node *create_new_node(int n)
{
ptr=new node;
ptr->info=n;
ptr->next=NULL;
return ptr; // This line is missing
}
Besides that it is a really bad idea to use global pointer variables!
Here
struct node
{
int info;
node *next;
}*start,*newptr,*save,*ptr;
you define the struct node but you also define 4 variables, i.e. 4 pointers to node. These variables will be global, i.e. available in all your code. Something that you should never do.
Instead make local variables as needed - for instance:
node *create_new_node(int n)
{
node *ptr; // Local variable instead of global
ptr=new node;
ptr->info=n;
ptr->next=NULL;
return ptr;
}
Then for the insert_beg change it so that it returns a new start pointer - like:
node* insert_beg(node* start, node *np)
{
np->next=start;
return np;
}
and use it in main like:
node* start = NULL;
...
...
start = insert_beg(start, newptr);
BTW - In modern C++ you would never use raw pointers and you would never write your own list. Use smart pointers instead of raw pointer. Use the standard containers instead of writing your own.
Hey guys I'm trying to run this code but I get segmentation fault when the compiler gets to the class functions.
This is the main function:
int main (int argc, char* argv[]){
cout<<"\t1.Add Program\n";
cout<<"\t2.Kill Program\n";
cout<<"\t3.Fragmentation\n";
cout<<"\t4.Print Memory\n";
cout<<"\t5.Exit"<<endl;
LinkedList Memory;
Memory.createMemory(); (I get the segmentation error on this line)
int choice;
cin>>choice;
cout<<"choice - "<<choice<<endl;
if (choice==1){
string programName;
cin>>programName;
cout<<"Program name - "<<programName<<endl;
int size;
cin>>size;
cout<<"Program size (KB) - "<<size<<endl;
int numpages;
if (size%4==0) numpages=size/4;
if (size%4!=0) numpages=size/4+1;
Memory.addProgram(numpages, programName);
return 0;
}
This is the class
class LinkedList{
private:
struct node{
string name;
node *next;
};
public:
void createMemory();
void addProgram(int val, string s);
void killProgram(string s1);
void print();
void fragmentation();
LinkedList(){head=NULL;};
};
And these are two of the class functions
void LinkedList::createMemory(){
int i=0;
node* temp;
temp = new node;
while(i<32){
temp->name="Free";
temp=temp->next;
i++;
}
};
void LinkedList::addProgram(int val, string s){
int i=0;
node* temp;
temp=new node;
while(temp->name!="Free")
temp=temp->next;
while(temp->name=="Free"){
while (i<val){
temp->name=s;
temp=temp->next;
i++;
}
}
cout<<"Program "<<s<<" added successfully: "<<val<<" page(s) used."<<endl;
};
The other functions in the class are similar to these two so they're all gonna have the same error.
The main function runs correctly, but when I call the class functions in the main i get the segmentation fault.
while(i<32){
temp->name="Free";
temp=temp->next;
i++;
}
In this snippet, you use null or uninitialized temp->next
Maybe there are more subtle errors in your code. Use a debugger.
Tip always to keep in keep in mind: in constructor initialize all members, not only selected.
In my code, I use constructors for struct too (some people advice otherwise)
In LinkedList::createMemory and LinkedList::addProgram, you are creating a new node in the scope of the function but you are not assigning such new node to a class variable. Therefore, when you exit your function, the pointer to the resource you created is lost and:
1) you leaked memory because you haven't called delete on the pointer
2) your class doesn't have any nodes
add a
node *_root;
variable to your LinkedList class and assign to it.
Now with this being said here's a couple of tips:
Don't use new like that, it is very easy to leak memory. Use std::unique_ptr so that resources are automatically cleared.
Use std::list if you want to have a LinkedList.
'createMemory()' Method that initializes the List got problem with memory allocation. Only the first node got memory allocated. You are re-assigning 'temp' with 'temp->next' which does not have memory allocated to it and accessing 'temp->name' which would cause the 'Segmentation fault'. If you are creating multiple nodes in an iterative fashion, you must allocate memory for each of the nodes in the loop. Use this stanford link as a reference to learn how to initialize Linked List: http://cslibrary.stanford.edu/103/LinkedListBasics.pdf
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
the code send error in this line
course["CS"].student=new Course*[1];
i want create linked list of courses contain linked list of students
here is the code
struct Student{
string name;
int id;
int grade;
Student(string n, int i, int gd ){
name=n;
id=i;
grade=gd;
}
};
struct Course{
string C_Name;
Student **student;
int index;
void add_student(Student *new_student){
student[++index]=new_student;
}
};
Course course[4];
void init(){
course["CS"].student=new Course*[1];
}
Your code doesn't contain any kind of linked list, but only plain arrays.
Apart from that, the last line (course["CS"].student=new Course*[1];) contains some invalid syntax.
An integral or enum type must be used to access an array (strings or char[] wont work)
Assigning a Course** to a Student** object is not allowed
A linked list contains of nodes each having a pointer to the next node. The last node usually has a pointer with value nullptr (C++11) or 0 (older standard). Note: There is also a so-called double linked list, where every node also stores a pointer to the previous one.
A node contains all the data, that you want it to store.
Example:
struct Node {
Node* next;
// other node data here
};
To create a linked list, you first start with one node and set next = nullptr; // 0. To add another node just create a new one and change the pointer of the first one.
Example:
Node* node1 = new Node();
node1 -> next = nullptr;
Node* node2 = new Node();
node2 -> next = nullptr;
node1 -> next = node2;
You start to see a pattern. To insert at the front just create a new Node and set its next to the first already existing node. To insert between two nodes, say node1 and node2:
node1 -> next = newNode;
newNode -> next = node2;
To make it nice one usually writes a wrapper class containing functions such as
InsertNodeAt(Node* node, uint index);
Node* GetNodeAt(uint index);
RemoveNodeAt(uint index);
Since you have two different types of objects (Student and Curse), you might want to use templates and avoid writing a linked list class for each type.
If you want to create your linked list yourself, I recommend doing some additional research (google is your friend) as I have only mentioned a few things.
If you don't mind using the c++ standard library you might be interested in using the already pre-made linked list classes std::forward_list (standard linked list) and std::list (double linked list).
in c++ you didn't defined course["string"], so you may not use "CS" as an index to a Course type object
and *.student is a class Student's object, not Course type
#include <iostream>
#include <stdexcept>
using namespace std;
struct Student{
string name;
int id;
int grade;
Student(string n, int i, int gd ){
name=n;
id=i;
grade=gd;
}
};
struct Course{
string C_Name;
Student **student;
int index;
void add_student(Student *new_student){
student[++index]=new_student;
}
};
Course course[4];
void init(){
// Need allocate space for a new object of class "Course"
Course course;
course.student = new Student*[1];// "student" is Student type but not Course
}
int main()
{
try{
init();
}
catch(...){
return -1;
}
std::cerr <<"your debug info" <<endl;
return 0;
}
And in my own opinion, in c++ you may try reference and it's counter in class Course's definition to class Student. Using printer in this way may cause error unexpected.