Disappearing of object inside variable of another object - c++

I got strange program behaviour and crashing.
I created class 'List', with array of pointers to objects of class 'Student'. I observe that I succesfully called 'Student' object in 'List' constructor. But I'm unable to call 'Student' object from any other 'List' methods.
I even checked the same line for testing inside 'List' constructor and 'push' method, resulting in program crash.
Here is testing line: cout << (studentBox[numb] -> getRef()) << endl;
Here is the problematic part of code:
#include <iostream>
using namespace std;
class Student
{
private:
int referenceNumb;
int markNumb;
public:
Student();
Student(int, int);
~Student();
int getRef();
int getMark();
};
class List
{
private:
int numb;
Student* studentBox[1000];
public:
List();
~List();
void push(int, int);
int getAVG();
};
int main()
{
List* base = NULL;
int x, y;
char mod;
do
{
cout << "Waiting for orders." << endl;
cout << "1 - Quit," << endl;
cout << "2 - Add new student," << endl;
cout << "3 - Calculate average mark," << endl;
cout << "0 - Create new list." << endl;
cin >> mod;
switch(mod)
{
case '0': base = new List(); break;
case '1': cout << "Bye."; break;
case '2':
if(base != NULL)
{
cout << "Specify student's reference number: "; cin >> x;
cout << "Specify student's mark: "; cin >> y;
base->push(x, y);
}
else cout << "List does not exist!" << endl;
break;
case '3':
if(base != NULL)
{
cout << "Average mark is equal: " << base->getAVG();
}
else cout << "List does not exist!";
cout << endl;
break;
default: cout << "Correct command required!" << endl; break;
}
}
while(mod!='1');
return 0;
}
Student::Student()
{
referenceNumb = NULL;
markNumb = NULL;
}
Student::Student(int r, int m)
{
referenceNumb = r;
markNumb = m;
}
Student::~Student()
{
referenceNumb = NULL;
markNumb = NULL;
cout << "pusto." << endl;
}
int Student::getRef()
{
return referenceNumb;
}
int Student::getMark()
{
return markNumb;
}
List::List()
{
int numb = 0;
studentBox[numb] = new Student();
cout << (studentBox[numb] -> getRef()) << endl;
}
List::~List()
{
}
void List::push(int x, int y)
{
cout << (studentBox[numb] -> getRef()) << endl;
if(studentBox[numb] != NULL)
{
studentBox[numb] = new Student();
cout << (studentBox[numb] -> getRef()) << endl;
}
else cout << "Hujnia" << endl;
}
int List::getAVG()
{
int temp = 0;
for(int i=0; i<numb; i++)
{
temp += studentBox[i]->getMark();
}
return (temp / numb);
}

There are a couple of major problems that I see. The first is that the numb member of the List isn't initialized.
List::List()
{
int numb = 0; // this creates a new local variable called numb, it doesn't
// initialize the numb member.
studentBox[numb] = new Student();
cout << (studentBox[numb] -> getRef()) << endl;
}
Do this instead:
List::List()
: numb(0) // initialize the numb member to zero.
{
studentBox[numb] = new Student();
cout << (studentBox[numb] -> getRef()) << endl;
}
Another problem is that numb appears to be meant to indicate the size of the list, but it is never changed when a new student is added.

Related

c++ set const char* member variable of class

When I am trying to assign a member variable, which is const char*, it just ends the program.
However, if I get some cin inputs before I assign a member variable, it works.
this is my NameCard.h
class NameCard {
private:
const char* name;
const char* companyName;
const char* phoneNumber;
enum grade{CLERK, SENIOR, ASSIST, MANAGER};
grade my_grade;
NameCard* nextCard;
NameCard* head;
public:
NameCard(const char*, const char*, const char*, int);
void setName();
void setCompanyName();
void setPhoneNumber();
void setMyGrade();
void setHead(NameCard*);
void setNextCard(NameCard*);
void findInfo(char*);
void printAll();
};
This is main.cpp
#include <iostream>
#include <cstring>
#include "NameCard.h"
using namespace std;
NameCard::NameCard(const char* a, const char* b, const char* c, int d){
name = a;
companyName = b;
phoneNumber = c;
switch(d){
case CLERK: my_grade = CLERK; break;
case SENIOR: my_grade = SENIOR; break;
case ASSIST: my_grade = ASSIST; break;
case MANAGER: my_grade = MANAGER; break;
}
cout << name << " " << companyName << " " << phoneNumber << " " << my_grade << endl;
}
void NameCard::setName(){
char* name;
cout << "type name." << endl;
cin >> name;
this->name = name;
cout << this->name << endl;
}
void NameCard::setCompanyName(){
char* company_name;
cout << "type company name." << endl;
cin >> company_name;
this->companyName = company_name;
cout << this->companyName << endl;
}
void NameCard::setPhoneNumber(){
char* phone_number;
cout << "type phone number." << endl;
cin >> phone_number;
phoneNumber = phone_number;
cout << phoneNumber;
};
void NameCard::setMyGrade(){
int input_grade;
cout << "type position. 1)CLERK 2) SENOIR 3) ASSIST 4)MANAGER" << endl;
cin >> input_grade;
switch(input_grade){
case CLERK: my_grade = CLERK; break;
case SENIOR: my_grade = SENIOR; break;
case ASSIST: my_grade = ASSIST; break;
case MANAGER: my_grade = MANAGER; break;
}
cout << input_grade;
};
void NameCard::setHead(NameCard* head){
this->head = head;
};
void NameCard::setNextCard(NameCard* next){
this->nextCard = next;
}
void NameCard::findInfo(char* target_name){
NameCard* temp;
temp = head;
while(temp != NULL){
if(temp->name == target_name){
cout << "name : " << temp->name << endl;
cout << "companyName : " << temp->companyName << endl;
cout << "phoneNumber : " << temp->phoneNumber << endl;
cout << "grade : " << temp->my_grade << endl;
break;
}
temp = temp->nextCard;
}
};
void NameCard::printAll(){
NameCard* temp;
temp = head;
while(temp!= NULL){
cout<< "----------------------------" << endl;
cout << "name : " << temp->name << endl;
cout << "companyName : " << temp->companyName << endl;
cout << "phoneNumber : " << temp->phoneNumber << endl;
cout << "grade : " << temp->my_grade << endl;
temp = temp->nextCard;
}
}
int main(){
int index = 0;
NameCard* head = new NameCard("test", "test", "test", 3);
NameCard* bef = NULL;
// char input[50];
// cout << "nmae ";
// cin >>input;
head->setName();
head->setPhoneNumber();
head->setCompanyName();
head->setMyGrade();
return 0;
}
And the problem is here. This is not working. The program ends right after it gets name from setName(). It just ends at the setName() cin >> name. it did not print name after then, and stopped.
int main(){
int index = 0;
NameCard* head = new NameCard("test", "test", "test", 3);
NameCard* bef = NULL;
// char input[50];
// cout << "nmae ";
// cin >>input;
head->setName();
head->setPhoneNumber();
head->setCompanyName();
head->setMyGrade();
return 0;
}
However, this is working fine. it gets the test input and executes all the code below.
int main(){
int index = 0;
NameCard* head = new NameCard("test", "test", "test", 3);
NameCard* bef = NULL;
char input[50];
cout << "test input ";
cin >>input;
head->setName();
head->setPhoneNumber();
head->setCompanyName();
head->setMyGrade();
return 0;
}
You are writing to memory you didn't allocate and most likely don't own.
Check this for example
void NameCard::setName(){
char* name;
cout << "type name." << endl;
cin >> name;
this->name = name;
cout << this->name << endl;
}
You declare char* name and try to read from cin into it. But name is just an uninitialized pointer.
One fix may be to declare name as an array, which also decays to a pointer (so it can be used as a pointer), but does have associated memory. Like this
char name[50];
Or if you want it to be dynamically allocated
char* name = new char[50];
// Use it and when you are done delete it
// Never forget to release memory allocated with new or you get a memory leak
delete[] name;
The key point is that the pointer needs to point to some memory block you know you can use. Note that in the example I allocated 50 chars, you have to make sure you never use (read/write) past the allocated memory, or you get the same error you have been getting and potentially program termination.
A safer alternative is to use std::string, which automatically handles memory for you, so you don't have to mind about allocation and releasing.
You could do something like
std::string name;
std::cin >> name;

Two codes; same logic and line of code, one works but other doesn't

I asked this question a couple of hours ago; I want to see if someone can now explain the problem.
One code is about separating items in a grocery; in the end you'll have two(2) bags; a fragileBag and a normalBag.
Other code separates passengers depending on the office they go for pickup; in the end you'll have three(3) types of passengers; ones that go to rio, ones that go to maya, and ones that request elsewhere.
Both codes use the same logic but the passenger code gives an error on a line that works perfectly on the grocery code.
Just to be clear, BOTH CODES RETURN VALUES OF STRING.
ERROR FROM THE PASSENGER CODE:
Error (active) E0304 no instance of overloaded function "std::vector<_Ty,_Alloc>::push_back [with _Ty=trans, _Alloc=std::allocator<trans>]" matches the argument list dataPractice2 C:\Users\javye\source\repos\dataPractice2\dataPractice2\main.cpp 82
and also:
Error C2664 'void std::vector<trans,std::allocator<_Ty>>::push_back(_Ty &&)': cannot convert argument 1 from 'std::string' to 'const _Ty &' dataPractice2 c:\users\javye\source\repos\datapractice2\datapractice2\main.cpp 82
//GROCERY FUNCTION
//separate function
void separateItems(vector<myBag>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getItem() == "eggs" || newMyVector[x].getItem() == "bread") {
fragileBag.push_back(newMyVector[x].getItem()); //NO PROBLEM HERE
newMyVector.pop_back();
}
else {
normalBag.push_back(newMyVector[x].getItem()); //OR HERE
newMyVector.pop_back();
}
}
}
//PASSENGER FUNCTION
//separate function
void separateP(vector<trans>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getXoLoc() == "rio") {
rioLoc.push_back(newMyVector[x].getXoLoc()); //PROBLEM HERE
newMyVector.pop_back();
}
else
if (newMyVector[x].getXoLoc() == "maya") {
mayaLoc.push_back(newMyVector[x].getXoLoc()); //HERE
newMyVector.pop_back();
}
else
elseLoc.push_back(newMyVector[x].getXoLoc()); //HERE
newMyVector.pop_back();
}
}
//GROCERY FULL CODE
//HEADER
#pragma once
#include<iostream>
#include<vector>
#include<string>
using namespace std;
#ifndef BAG_H
#define BAG_H
class myBag {
public:
myBag(); //default constructor
myBag(string anItemName); //overload constructor
void addItem(string anItemName); //mutator
string getItem();//accessor
private:
string itemName;
};
#endif
//SOURCE
#include"bag.h"
myBag::myBag() {
addItem("");
}
myBag::myBag(string anItemName) {
addItem(anItemName);
}
void myBag::addItem(string anItemName) {
itemName = anItemName;
}
string myBag::getItem() {
return itemName;
}
//MAIN
#include"bag.h"
void inputItems(vector<myBag>&); //input data function prototype
void displayQuantity(vector<myBag>&); //display data function prototype
void separateItems(vector<myBag>&); //function that separates items; func prototype
void fragBag(vector<myBag>&); //fragile bag function prototype
void norBag(vector<myBag>&); //normal bag function prototype
vector<myBag> myVector; //main vector
vector<myBag> fragileBag, normalBag; //seconday vectors
string item; //global item variable
int main() {
int option;
try {
do {
cout << "\tMENU"
<< endl << "1) Input Items"
<< endl << "2) Display Quantity"
<< endl << "3) Separate (IMPORTANT)"
<< endl << "4) Display Items in Fragile Bag"
<< endl << "5) Display Items in Normal Bag"
<< endl << "6) Exit Program"
<< endl << endl << "Choose: ";
cin >> option;
if (option > 6) {
throw 404;
}
switch (option) {
case 1: //input
system("cls");
inputItems(myVector);
system("pause");
system("cls");
break;
case 2://display
system("cls");
displayQuantity(myVector);
system("pause");
system("cls");
break;
case 3: //separate
system("cls");
separateItems(myVector);
system("pause");
system("cls");
break;
case 4: //fragile
system("cls");
fragBag(myVector);
system("pause");
system("cls");
break;
case 5: //normal
system("cls");
norBag(myVector);
system("pause");
system("cls");
break;
case 6: //exit
exit(0);
}
} while (option != 6);
}
catch(int x){
cout << "ERROR, OPTION DOESN'T EXITS" << endl;
system("pause");
}
}
//input function
void inputItems(vector<myBag>& newMyVector) {
do {
cout << "Enter grocery items || enter letter X to stop: ";
cin >> item;
if (item != "x")
newMyVector.push_back(myBag(item));
} while (item != "x");
}
//display function
void displayQuantity(vector<myBag>& newMyVector) {
try {
for (int x = 0; x < newMyVector.size(); ++x) {
if (x == 0) {
cout << "Store bag has " << newMyVector.size() << " items in it. These are: " << endl;
}
cout << newMyVector[x].getItem() << endl;
}
if (newMyVector.empty())
throw 404;
}
catch (int x) {
cout << "ERROR " << x << " ,QUANTITY NOT FOUND" << endl;
}
}
//separate function
void separateItems(vector<myBag>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getItem() == "eggs" || newMyVector[x].getItem() == "bread") {
fragileBag.push_back(newMyVector[x].getItem()); //PROBLEM WOULD APPEAR HERE, BUT DOESN'T, UNLIKE THE OTHER CODE
newMyVector.pop_back();
}
else {
normalBag.push_back(newMyVector[x].getItem());
newMyVector.pop_back();
}
}
}
//fragile bag function
void fragBag(vector<myBag>& newMyVector) {
try {
for (int x = 0; x < fragileBag.size(); ++x) {
if (x == 0) {
cout << "The fragile bag has " << fragileBag.size() << " items in it. These are: " << endl;
}
cout << fragileBag[x].getItem() << endl;
}
if (fragileBag.empty()) {
throw 404;
}
}
catch (int x) {
cout << "ERROR " << x << " ,FRAGILE BAG EMPTY" << endl;
}
}
//normal bag function
void norBag(vector<myBag>& newMyVector) {
try {
for (int x = 0; x < normalBag.size(); ++x) {
if (x == 0) {
cout << "The normal bag has " << normalBag.size() << " items in it. These are: " << endl;
}
cout << normalBag[x].getItem() << endl;
}
if (normalBag.empty()) {
throw 404;
}
}
catch (int x) {
cout << "ERROR " << x <<" , NORMAL BAG EMPTY" << endl;
}
}
//PASSENGER FULL CODE
//HEADER
#pragma once
#include<iostream>
#include<vector>
#include<string>
using namespace std;
#ifndef TRANSPORT_H
#define TRANSPORT_H
class trans {
public:
trans();
trans(string aName, string anXoLoc, string anXfLoc, string aTime, string aCellNum);
void setName(string aName);
void setXoLoc(string anXoLoc);
void setXfLoc(string anXfLoc);
void setTime(string aTime);
void setCellNum(string aCellNum);
string getName();
string getXoLoc();
string getXfLoc();
string getTime();
string getCellNum();
private:
string name;
string xoLoc; //offices
string xfLoc; //destination
string time;
string cellNum;
};
//SOURCE
#include"transport.h"
trans::trans() {
setName("");
setXoLoc("");
setXfLoc("");
setTime("");
setCellNum("");
}
trans::trans(string aName, string anXoLoc, string anXfLoc, string aTime, string aCellNum) {
setName(aName);
setXoLoc(anXoLoc);
setXfLoc(anXfLoc);
setTime(aTime);
setCellNum(aCellNum);
}
void trans::setName(string aName) {
name = aName;
}
void trans::setXoLoc(string anXoLoc) {
xoLoc = anXoLoc;
}
void trans::setXfLoc(string anXfLoc) {
xfLoc = anXfLoc;
}
void trans::setTime(string aTime) {
time = aTime;
}
void trans::setCellNum(string aCellNum) {
cellNum = aCellNum;
}
string trans::getName() {
return name;
}
string trans::getXoLoc() {
return xoLoc;
}
string trans::getXfLoc() {
return xfLoc;
}
string trans::getTime() {
return time;
}
string trans::getCellNum() {
return cellNum;
}
#endif
//MAIN
#include"transport.h"
void inputInfo(vector<trans> &);
void displayInput(vector<trans>&);
void separateP(vector<trans>&);
void rio(vector<trans>&);
void maya(vector<trans>&);
void elsewhere(vector<trans>&);
vector<trans> myVector;
vector<trans> rioLoc, mayaLoc, elseLoc;
string newName;
string newXoLoc; //offices
string newXfLoc; //destination
string newTime;
string newCellNum;
//main not ready. Creating each function one by one to them make it look nice
int main() {
int option;
do {
cout << "MENU"
<< endl << "1) input "
<< endl << "2) output "
<< endl << "3) separate"
<< endl << "4) rio passengers"
<< endl << "5) maya passengers"
<< endl << "6) elsewhere passengers";
cin >> option;
switch(option){
case 1:
inputInfo(myVector);
break;
case 2:
displayInput(myVector);
break;
case 3:
separateP(myVector);
break;
case 4:
rio(myVector);
break;
case 5:
maya(myVector);
break;
case 6:
elsewhere(myVector);
break;
case 7:
exit(0);
}
} while (option != 7);
system("pause");
}
void inputInfo(vector<trans> &newMyVector) {
int charSize;
cout << "How many passangers to register: ";
cin >> charSize;
for (int x = 0; x < charSize; ++x) {
cout << "Name of passanger: ";
cin >> newName;
cout << "Office: ";
cin >> newXoLoc;
cout << "Destination: ";
cin >> newXfLoc;
cout << "Time of pickup: ";
cin >> newTime;
cout << "Cellphone: ";
cin >> newCellNum;
if (charSize != 0)
newMyVector.push_back(trans(newName, newXoLoc, newXfLoc, newTime, newCellNum));
}
}
void displayInput(vector<trans>& newMyVector) {
for (int x = 0; x < newMyVector.size(); ++x) {
if (x == 0) {
cout << "There are " << newMyVector.size() << " passengers. These are: " << endl;
}
cout << "-----------------------------Passenger #" << x + 1 << endl;
cout << newMyVector[x].getName() << endl;
cout << newMyVector[x].getXoLoc() << endl;
cout << newMyVector[x].getXfLoc() << endl;
cout << newMyVector[x].getTime() << endl;
cout << newMyVector[x].getCellNum() << endl;
}
}
void separateP(vector<trans>& newMyVector) {
for (int x = newMyVector.size() - 1; x >= 0; --x) {
if (newMyVector[x].getXoLoc() == "rio") {
rioLoc.push_back(newMyVector[x]);
newMyVector.pop_back();
}
else
if (newMyVector[x].getXoLoc() == "maya") {
mayaLoc.push_back(newMyVector[x]);
newMyVector.pop_back();
}
else
elseLoc.push_back(newMyVector[x]);
newMyVector.pop_back();
}
}
void rio(vector<trans>& newMyVector) {
for (int x = 0; x < rioLoc.size(); ++x) {
if (x == 0) {
cout << "Num. of passangers to pickup in Rio Piedras is " << rioLoc.size() << " , these are: " << endl;
}
cout << rioLoc[x].getName() << endl;
cout << rioLoc[x].getXoLoc() << endl;
cout << rioLoc[x].getXfLoc() << endl;
cout << rioLoc[x].getTime() << endl;
cout << rioLoc[x].getCellNum() << endl;
}
}
void maya(vector<trans>& newMyVector) {
for (int x = 0; x < mayaLoc.size(); ++x) {
if (x == 0) {
cout << "Num. of passangers to pickup in Mayaguez is " << mayaLoc.size() << " , these are: " << endl;
}
cout << mayaLoc[x].getName() << endl;
cout << mayaLoc[x].getXoLoc() << endl;
cout << mayaLoc[x].getXfLoc() << endl;
cout << mayaLoc[x].getTime() << endl;
cout << mayaLoc[x].getCellNum() << endl;
}
}
void elsewhere(vector<trans>& newMyVector) {
for (int x = 0; x < elseLoc.size(); ++x) {
if (x == 0) {
cout << "Num. of passangers to pickup in elsewhere is " << elseLoc.size() << " , these are: " << endl;
}
cout << elseLoc[x].getName() << endl;
cout << elseLoc[x].getXoLoc() << endl;
cout << elseLoc[x].getXfLoc() << endl;
cout << elseLoc[x].getTime() << endl;
cout << elseLoc[x].getCellNum() << endl;
}
}
To explain why the second code does not work I first have to explain why the first code appears to work.
myBag::myBag(string anItemName)
can make a bag out of a string. It is a Conversion Constructor. So when
fragileBag.push_back(newMyVector[x].getItem());
is compiled, the compiler quietly inserts a call to the myBag(string) constructor and you get something more like
fragileBag.push_back(myBag(newMyVector[x].getItem()));
which makes no sense logically. It says turn an item in a bag into a bag with one item and insert this new bag into still another bag, fragileBag.
When you look more closely at myBag, you see that it isn't a bag at all. It is a single item and should be renamed to myItem or discarded all together in favour of an all-new all-different myBag that is a wrapper around a vector of string where the strings represent items. This makes
myBag fragileBag;
the real bag.
In other words, the only reason the working code works is it doesn't actually do what the naming implies it does. The code compiles and produces the expected result, but is semantically troubled.
This leads to the confusion with
rioLoc.push_back(newMyVector[x].getXoLoc());
rioLoc is a vector<trans> and can only hold trans. There is no trans::trans(string) to convert a string to a trans so the faulty logic of the grocery code is exposed. As bag and item have been intertwined in grocery, passenger and transport are combined here.
The fix for grocery described above is relatively straight forward. Passenger will need a slightly different solution with both a passenger class to describe the passengers and a transport class to describe the means of transport. transport will have a vector<passenger> member to contain its passengers as well as methods to add and remove the passengers and possibly book-keeping to track the location of the transport, details incompletely specified by the question.
Both codes are pushing string values into a vector that does not hold string values.
Your grocery code uses a vector of myBag objects. The code works because myBag has a non-explicit constructor that takes a single string as input, so the compiler is able to implicitly construct a temporary myBag object to push into the vector.
Your passenger code uses a vector of trans objects. The code fails because trans does not have a constructor that takes a single string as input, so the compiler cannot construct a temporary trans to push into the vector.

function that merges two singly linked lists to form a third one

So i am writing a programm where user fills two linked lists with integers, and now i need to create a function that creates third linked list with values from both first and second lists without duplicates.
Here is the code i have right now:
#include <iostream>
#include <stdlib.h>
using namespace std;
struct node
{
int info;
node *next;
node (int i, node *n=NULL)
{
info = i;
next = n;
}
~node()
{
cout <<"NODE CONTAINING \"" << info << "\" WAS DELETED!" << endl;
}
};
struct list
{
node* startList1, *lastList1, *startList2, *lastList2;
int menuOption;
int nodeCount1=0, nodeCount2=0;
list() {
startList1 = NULL;
startList2 = NULL;
}
void addList1(node *p)
{
int n;
cout << "PLEASE INPUT VALUE WHICH YOU WANT IN THE NODE:";
cin >> n;
p = new node(n);
nodeCount1++;
if(startList1==NULL)
{
startList1 = lastList1 = p;
}
else
{
lastList1->next = p;
lastList1 = p;
}
}
void printList1(node *pr)
{
node *pr;
for (pr=startList1; pr!=NULL; pr=pr->next)
{
cout << pr->info << endl;
}
}
void addList2(node *q)
{
int n;
cout << "PLEASE INPUT VALUE WHICH YOU WANT IN THE NODE:";
cin >> n;
q = new node(n);
nodeCount2++;
if(startList2==NULL)
{
startList2 = lastList2 = q;
}
else
{
lastList2->next = q;
lastList2 = q;
}
}
void printList2(node *pr)
{
for (pr=startList2; pr!=NULL; pr=pr->next)
{
cout << pr->info << endl;
}
}
// this just prints first and second lists to show what is inside..
void printBoth(node *pr, node *qr)
{
cout << "Elements of the first list:" << endl;
for (pr=startList1; pr!=NULL; pr=pr->next)
{
cout << pr->info << endl;
}
cout << "Elements of the second list:" << endl;
for (pr=startList2; pr!=NULL; pr=pr->next)
{
cout << pr->info << endl;
}
}
void printMenu()
{
cout << "MENU" << endl;
cout << "(1) ADD ELEMENT LIST1." << endl;
cout << "(2) PRINT LIST1" << endl;
cout << "(3) ADD ELEMENT LIST2" << endl;
cout << "(4) PRINT LIST2" << endl;
cout << "(5) PRINT BOTH LISTS" << endl;
cout << "(6) USE MERGE FUNCTION" << endl;
cout << "(7) TO EXIT" << endl;
cin >> menuOption;
system ("cls");
};
void dragons()
{
node *temp1 = startList1;
node *temp2 = startList2;
while(temp1)
{
temp1 = startList1->next;
delete startList1;
startList1=temp1;
}
while(temp2)
{
temp2 = startList2->next;
delete startList2;
startList2=temp2;
}
};
};
int main()
{
struct node *p = NULL, *q = NULL;
list s;
s.printMenu();
node* list1;
node* list2;
node* sorting;
while(s.menuOption!=7)
{
switch (s.menuOption)
{
case 1: s.addList1(list1);
break;
case 2: s.printList1(list1);
break;
case 3: s.addList2(list2);
break;
case 4: s.printList2(list2);
break;
case 5:s.printBoth(list1, list2);
break;
case 6:s.merge();
break;
default: cout << "SOMETHING WENT WRONG!!!!" << endl;
break;
}
system ("pause");
system ("cls");
s.printMenu();
}
s.dragons();
return 0;
}
So now user can input elements to both lists and see them, but how can i create a function, that will merge those lists without duplicate values? for example:
List1 = 1, 2, 3, 6, 8;
List2 = 2, 4, 5, 7, 8;
Merged list = 1, 2, 3, 4, 5, 7, 8; (can be whatever order actually, it doesn't matter)
Any advice would be appreciated! Thanks!
Here is a version of your code, but using an STL list container to provide the linked list, and this provides its own functions that will achieve what you want. This code is for demonstration, and is not optimised for efficiency, it just shows one possible method of merging unique elements from two lists. (For this to work, the list requires its elements to be sorted, and you need to provide predicates for "less than" and "equal to" for the nodes in the list.)
(Its true that it takes time to learn some of the STL containers and functions, but many people would recommend doing that instead of trying to create your own raw-pointer-based linked list from scratch.)
Hope this helps, or is of interest.
#include <iostream>
#include <stdlib.h>
#include <list>
struct node
{
int info;
node (int i)
{
info = i;
}
~node()
{
//std::cout <<"NODE CONTAINING \"" << info << "\" WAS DELETED!" << std::endl;
}
};
bool nodeLess(node n1, node n2)
{
return n1.info < n2.info;
}
bool nodeEqual(node n1, node n2)
{
return n1.info == n2.info;
}
struct mylist
{
int menuOption;
std::list<node> list1;
std::list<node> list2;
void addList(std::list<node>& l)
{
int x;
std::cout << "PLEASE INPUT VALUE WHICH YOU WANT IN THE NODE: ";
std::cin >> x;
node n(x);
l.push_back(n);
}
void printList(const std::list<node>& l)
{
for (std::list<node>::const_iterator it = l.cbegin(); it != l.cend(); ++it)
{
std::cout << it->info << std::endl;
}
}
void addList1() { addList(list1); }
void addList2() { addList(list2); }
void printList1() { printList(list1); }
void printList2() { printList(list2); }
// this just prints first and second lists to show what is inside..
void printBoth()
{
std::cout << "Elements of the first list:" << std::endl;
printList1();
std::cout << "Elements of the second list:" << std::endl;
printList2();
}
void simpleMerge()
{
std::list<node> merged;
merged.insert(merged.end(), list1.begin(), list1.end());
merged.insert(merged.end(), list2.begin(), list2.end());
std::cout << "CONTENTS OF LIST1 THEN LIST2: " << std::endl;
printList(merged);
}
void uniqueSortMerge()
{
std::list<node> sorted1(list1.begin(), list1.end());
std::list<node> sorted2(list2.begin(), list2.end());
sorted1.sort(nodeLess);
sorted2.sort(nodeLess);
sorted1.unique(nodeEqual);
sorted2.unique(nodeEqual);
std::list<node> merged;
std::merge(sorted1.begin(), sorted1.end(),
sorted2.begin(), sorted2.end(),
std::back_inserter(merged),
nodeLess);
std::cout << "UNIQUE CONTENTS OF LIST1 AND LIST2 SORTED AND MERGED: " << std::endl;
printList(merged);
}
void printMenu()
{
std::cout << "MENU" << std::endl;
std::cout << "(1) ADD ELEMENT LIST1." << std::endl;
std::cout << "(2) PRINT LIST1" << std::endl;
std::cout << "(3) ADD ELEMENT LIST2" << std::endl;
std::cout << "(4) PRINT LIST2" << std::endl;
std::cout << "(5) PRINT BOTH LISTS" << std::endl;
std::cout << "(6) USE SIMPLE MERGE FUNCTION" << std::endl;
std::cout << "(7) USE UNIQUE, SORT AND MERGE FUNCTION" << std::endl;
std::cout << "(8) TO EXIT" << std::endl;
std::cin >> menuOption;
system ("cls");
};
void dragons()
{
list1.clear();
list2.clear();
};
};
int main()
{
mylist s;
do
{
s.printMenu();
switch (s.menuOption)
{
case 1:
s.addList1();
break;
case 2:
s.printList1();
break;
case 3:
s.addList2();
break;
case 4:
s.printList2();
break;
case 5:
s.printBoth();
break;
case 6:
s.simpleMerge();
break;
case 7:
s.uniqueSortMerge();
break;
case 8:
break;
default:
std::cout << "SOMETHING WENT WRONG!!!!" << std::endl;
break;
}
system ("pause");
system ("cls");
} while(s.menuOption != 8);
s.dragons();
return 0;
}

Read Access Violation Code: 0xCDCDCDE1 and Code :0xCDCDCDE1

I'm doing a Shopping Mall project in Link List C++. In which I have to insert new Shop,Search Shop, Delete Shop, Count Shops and Display all. I written some of code.
I wrote the code but:
(1) it give error in input after when I input 2nd time and press input at last input i gives following Exception.
"Exception thrown: read access violation.
std::_String_alloc > >::_Mysize(...) returned 0xCDCDCDE1."
(2) When I display it give following Exception:
Exception thrown: read access violation.
temp was 0xCDCDCDCD.
Here is main.
int main()
{
ShoppingMallList* shopList=new ShoppingMallList();
string name="";
int shopNumber;
string brandShop;
int floor;
string shoptype;
do
{
system("cls");
cout << "**************WELCOME TO MALL**************\n1: Add Shop\n2: Search Shop\n3: Count Shops\n4:Display Shops\n5: Quit" << endl;
int option;
cin >> option;
switch (option)
{
case 1:
{
input(name, shopNumber, brandShop, floor, shoptype);
shopList->Insert(name, shopNumber, brandShop, floor, shoptype);
}
break;
case 2:
{
string name1;
cin.clear();
cin.ignore();
cout << "Enter Name of Shop to Search: ";
getline(cin, name1);
shopList->search(name1);
}
break;
case 4:
{
shopList->Print();
}
break;
case 5:
{
shopList->~ShoppingMallList();
exit(0);
}
break;
default:
continue;
}
system("pause");
shopList;
} while (true);
return 0;
}
void input(string& name, int& shopNumber, string& brandShop, int& floor, string& shoptype)
{
char temp;
cin.clear();
cin.ignore();
cout << "Enter Name: ";
getline(cin, name);
cout << "Enter Shop Number: ";
cin >> shopNumber;
cin.clear();
cin.ignore();
cout << "Enter Brand(yes/no): ";
getline(cin, brandShop);
cout << "Enter Floor: ";
cin >> floor;
cin.clear();
cin.ignore();
cout << "Enter Shop Type: ";
getline(cin, shoptype);
}
Here is shoppingMall.h
class ShoppingMall
{
friend std::ostream& operator<<(std::ostream& cout, const ShoppingMall& shop);
friend class ShoppingMallList;
public:
ShoppingMall(std::string& , int&, std::string&, int&, std::string&);
private:
std::string name;
int shopNumber;
std::string brandshop;
int floor;
std::string shopType;
ShoppingMall* link;
};
ShoppingMall::ShoppingMall(std::string& name , int& shopNumber, std::string& brandShop, int& floor, std::string& shoptype) : name(name), shopNumber(shopNumber), brandshop(brandShop), floor(floor), shopType(shoptype)
{
}
std::ostream& operator<<(std::ostream& cout, const ShoppingMall& shop)
{
cout << "Name: " << shop.name << std::endl << "Shop Number: " << shop.shopNumber << std::endl << "Brand Shop: " << shop.brandshop << std::endl << "Floor: " << shop.floor << std::endl << "Shop Type: " << shop.shopType << std::endl;
return cout;
}
And here is ShoppingMallList.h header file.
class ShoppingMallList
{
public:
ShoppingMallList();
void addToHead(std::string&, int&, std::string&, int&, std::string&);
void Insert(std::string&, int&, std::string&, int&, std::string&);
void Print();
int getsize();
void deleteShop(std::string&);
void search(std::string&);
private:
ShoppingMall* head;
int size;
};
ShoppingMallList::ShoppingMallList() : head(0), size(0)
{
}
void ShoppingMallList::addToHead(std::string& name, int& shopNumber, std::string& brandShop, int& floor, std::string& shoptype)
{
ShoppingMall* temp = new ShoppingMall(name,shopNumber,brandShop,floor,shoptype);
if (head==0)
{
head = temp;
}
else
{
temp->link = head;
head = temp;
}
size++;
}
int ShoppingMallList::getsize()
{
return size;
}
void ShoppingMallList::Print()
{
ShoppingMall* temp = head;
while ( temp != 0 )
{
std::cout << "Name: " << temp->name << std::endl << "Shop Number: " << temp->shopNumber << std::endl << "Brand Shop: " << temp->brandshop << std::endl << "Floor: " << temp->floor << std::endl << "Shop Type: " << temp->shopType << std::endl;
temp = temp->link;
}
}
void ShoppingMallList::Insert(std::string& name, int& shopNumber, std::string& brandShop, int& floor, std::string& shoptype)
{
ShoppingMall* newShop = new ShoppingMall(name, shopNumber, brandShop, floor, shoptype);
//case-1 EmptyList
if ( head == 0 )
{
head = newShop;
}
else
{
ShoppingMall* temp = head;
ShoppingMall* previous = 0;
// Traversing link to find insert location
while (temp!=0)
{
if ( temp->name >= newShop->name )
{
break;
}
else
{
previous = temp;
temp = temp->link;
}
}
//case-2 Adding To Head
if ( temp == head )
{
newShop->link = head;
head = newShop;
}
//case-3 Adding After Head
else
{
newShop->link = temp;
previous->link = newShop;
}
}
size++;
}
void ShoppingMallList::deleteShop(std::string& name)
{
ShoppingMall* temp=head;
ShoppingMall* previous = 0;
if (head == 0)
{
//Case-1 If There is no node
std::cout << "Shop cannot be deleted becasue the there no Node " << std::endl;
}
//Traversing Node to find node to delete
while (temp!=0)
{
if ( temp->name == name )
{
break;
}
else
{
previous = temp;
temp = temp->link;
}
}
//case-2 If Shop with name passed not found
if ( temp == 0 )
{
std::cout << "Shop of name " << name << " not found!" << std::endl;
}
else
{
//case-3 Delete node from head Node
if ( temp == head )
{
head = head->link;
}
//delete other than head shop
else
{
previous->link = temp->link;
}
delete temp;
size--;
}
}
void ShoppingMallList::search(std::string& name)
{
ShoppingMall* tempShop = head;
while ( tempShop != 0 )
{
if (tempShop->name == name)
{
std::cout << "Name: " << tempShop->name << std::endl << "Shop Number: " << tempShop->shopNumber << std::endl << "Brand Shop: " << tempShop- >brandshop << std::endl << "Floor: " << tempShop->floor << std::endl << "Shop Type: " << tempShop->shopType << std::endl;
}
else
{
tempShop = tempShop->link;
}
}
if ( tempShop == 0 )
{
std::cout << "Shop of name " << name << " not found!" << std::endl;
}
}
link field of ShoppingMall class is not initialized in constructor and contains some random rubbish. All list iterations like:
while ( temp != 0 )
{
// Code skipped for simplicity
temp = temp->link;
}
could cause Access Violation because condition temp != 0 never met and skipped code access memory at random address.
To fix it:
ShoppingMall::ShoppingMall(const std::string& name, int shopNumber, std::string& brandShop, int floor, const std::string& shoptype)
: link(nullptr), name(name), shopNumber(shopNumber), brandshop(brandShop), floor(floor), shopType(shoptype)
{
}

C++ why does my array not pop into my stack?

I created an array for studentrecords and am supposed to pop it into my stack.. well everything works except for my stack.pops and stack.pushes in MAIN...I am so close to finishing this program I am wondering if anyone knows any solutions?
#include <iostream>
#include <list>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <string>
using namespace std;
class Studentrecords
{
private:
struct student
{
string name;
string address;
int ID;
double gpa;
};
student *stackArray;
int stackSize;
int top;
public:
Studentrecords();
Studentrecords(int size);
~Studentrecords();
void push(string name, string address, int id, double gpa);
void pop();
bool isFull() const;
bool isEmpty() const;
void display();
};
Studentrecords::Studentrecords(int size)
{
stackArray = new student[size];
top = -1;
}
Studentrecords::Studentrecords()
{
stackSize = 20;
stackArray = new student[stackSize];
top = -1;
}
Studentrecords::~Studentrecords()
{
delete [] stackArray;
}
void Studentrecords::push (string name, string address, int id, double gpa)
{
if (isFull())
{
cout << "The stack is full!" << endl;
}
else
{
student newStudent;
newStudent.name = name;
newStudent.address= address;
newStudent.ID = id;
newStudent.gpa = gpa;
stackArray[top] = newStudent;
top++;
}
}
void Studentrecords::pop ()
{
if (isEmpty())
{
cout << "The stack is empty!" << endl;
}
else
{
cout << stackArray[top-1].name << endl;
cout << stackArray[top-1].address << endl;
cout << stackArray[top-1].ID << endl;
cout << stackArray[top-1].gpa << endl;
top--;
}
}
bool Studentrecords::isFull() const
{
bool status;
if (top == stackSize - 1)
status = true;
else
status = false;
return status;
}
bool Studentrecords::isEmpty() const
{
bool status;
if (top == -1)
status = true;
else
status = false;
return status;
}
void Studentrecords::display()
{
for (int i = 0; i< top; i++)
{
cout << stackArray[i].name << endl;
cout << stackArray[i].address << endl;
cout << stackArray[i].ID << endl;
cout << stackArray[i].gpa << endl << endl;
}
}
int main()
{
int catchVar;
Studentrecords stack();
cout << "Pushing 1st";
stack.push("Jonny", "123 ave", 2343, 3.2);
cout << "pushing 2nd";
stack.push("Robby", "123 ave", 2343, 3.2);
cout << "Popping ";
stack.pop(catchVar);
cout << catchVar << endl;
cout << "Popping ";
stack.pop(catchVar);
cout << catchVar << endl;
return 0;
}
Studentrecords stack();
Does not declare a Studentrecords named stack, it declares a function named stack that returns a Studentrecords. Change it to
Studentrecords stack;
Also your class needs at least a copy constructor and assignment operator.
Can you post the compiler's error?
Or the produced output VS the expected output?
Without that, I'll have to say that your pop function doesn't take arguments and you are passing it catchVar... that would be a compiler error.