std::bad_alloc at memory location 0x002b123c - c++

I am making a small program. First I made a Header File:
private:
string UserName, Password;
public:
void setUN(string);
void setP(string);
string getUN();
Then in my cpp file:
void UserInfo::setUN(string un){
UserName = un;
}
string UserInfo::getUN(){
return UserName;
}
After that in my main I make a object:
UserInfo addUser[100];
to add users
cout<<"Enter Username : ";
getline(cin,tUN);
addUser[0].setUN(tUN);
After that in my other function void LoginScreen()
I made the same object:
UserInfo addUser[100];
string EUN, EP;
system("cls");
cout<<"Enter Username : ";
cin>>EUN;
cout<<endl;
cout<<"Enter Password : ";
//cin>>EP;
for( int a = 0; a <= 100; a++){
if (EUN == addUser[a].getUN()){
system("cls");
cout<<"OMG HELP MEEE ";
break;
}
}
It works fine when till get to this for loop and gives this error:
std::bad_alloc at memory location 0x002b123c
Can you tell me what the error means and how can I get rid of this.

UserInfo addUser[100]; has elements indexed from 0 - 99.
So fix:-
for( int a = 0; a <= 100; a++){
^^This should be a < 100
}

Related

Program crashes upon calling member function of an object pointer

As the title says, whenever I try to call a getter function to return the value of a private variable in an object pointer that is in a vector, it crashes. This causes my 2 other functions useless.
I know command == display and command == summary are not working properly. I did some debugging and found out that whenever I try to cout<<P_obj[i]->getnumber() for example, I crash.
Here is my code:
#include <string>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <cstring>
#include <vector>
#include <cstdio>
using namespace std;
class stock {
private:
int sharenumber;
float shareprice;
string sharename;
public:
stock(int x, string y,float z)
:sharenumber(x),sharename(y),shareprice(z)
{
}
int returnnumber(){
return sharenumber;
}
string returnname(){
return sharename;
}
float returnprice(){
return shareprice;
}
};
bool ispositive(int x){
bool a = false;
if (x>0){a = true;}
return a;
}
void buy(vector <stock*> list,int size){
int amount;
float price;
string symbol;
cout<<"Please enter the number of shares, the share symbol and the price of the share to make your purchase.\n";
do{
cout<<"Enter the amount: ";
cin>>amount;
if (ispositive(amount)==false){
cout<<"Please enter a positive number for the amount!\n";
}
}while(ispositive(amount)==false);
cout<<"Enter the symbol: ";
cin>>symbol;
do{
cout<<"Enter the stock price: $ ";
cin>>price;
if (ispositive(price)==false){
cout<<"Please enter a positive number for the price!\n";
}
}while(ispositive(price)==false);
list.push_back(new stock(amount,symbol,price));
cout<<"Your purchase has been made. Thank you for your time.\n\n";
}
void summary(vector <stock*> list,int size){
float cost = 0;
int stocktotal = 0;
for (int i = 0; i < size;i++){
cost = cost + (list[i]->returnprice()*list[i]->returnnumber());
stocktotal = stocktotal + list[i]->returnnumber();
}
cout<<"\nUser has made "<<size<<" purchases in total. The total number of stocks bought is "<<stocktotal<<". The total cost is "<<cost<<"."<<endl<<endl;
}
int main(int argc, char *argv[])
{
vector <stock*> P_obj;
bool cont = true;
bool last_cont = true;
char * check;
bool signal = false;
string command;
char done;
if (argc>1){
check = strstr(argv[1],".txt");
if (check!= NULL){
fstream tester;
tester.open(argv[1]);
if (tester.is_open()){
signal=true;}
}else{cout<<"Error has occurred. Please enter correct data file name with .txt extension.";}
if (signal){
cout<<"\nWelcome to the Golden Sacks! Enter a command to start your stock trading career.\n\n";
ofstream user_data(argv[1]);
while(cont==true){
bool e_valid = false;
cout<<"Enter command here: ";
cin>>command;
if (command == "buy"){
buy(P_obj,P_obj.size());
}
if (command == "summary"){
summary(P_obj,P_obj.size());
}
if (command == "display"){
cout<<"\nList of all purchases:\n";
for (int y = 0; y < P_obj.size(); y++){
cout<<P_obj[y]->returnnumber()<<" "<<P_obj[y]->returnname()<<" "<<"$"<<fixed<<setprecision(2)<<P_obj[y]->returnprice()<<endl;
}
cout<<endl;
}
if (command=="help"){
cout<<"Command list:\n";
cout<<left<<setw(2)<<"- buy\n";
cout<<left<<setw(2)<<"- display\n";
cout<<left<<setw(2)<<"- summary\n";
cout<<left<<setw(2)<<"- find <stock-symbol>\n";
cout<<left<<setw(2)<<"- amount>= <purchase-amount>\n";
cout<<left<<setw(2)<<"- help\n";
cout<<left<<setw(2)<<"- exit\n\n\n";
}
if (command == "exit"){
while (last_cont == true){
cout<<"Are you sure you want to quit? (Yy/Nn):";
cin>>done;
if (done == 'Y'||done == 'y'||done =='N'||done =='n'){
last_cont=false;
if(done=='Y'||done=='y'){
cont = false;
cout<<"Thank you for using Golden Sacks. We hope to see you soon!\n";
}
}else {cout<<"Please enter only Y|N or y|n, try again.\n\n";}
}
}
} //end of loop
for (int i = 0; i < P_obj.size(); i++){
user_data<<P_obj[i]->returnnumber()<<" "<<P_obj[i]->returnname()<<" "<<"$"<<fixed<<setprecision(2)<<P_obj[i]->returnprice()<<endl;
}
}
}else {cout<<"Too few arguments, enter a data file name with .txt extension to continue";}
}
vector <stock*> P_obj;
is not properly allocated. //memory leak
stock is not a user defined type like int or double.
so if you are using it as a pointer, use RAII technique with it, deallocate it in it's destructure
eg:
class Stock{
int* x{nullptr};
public:
Stock(...);//allocated here
~Stock(..);//deallocate here
};
you can further more defined new and delete operators

Segmentation fault (core dumped) C++ Object Oriented Programming

I'm a student of system engineering, 2nd semester of the ULA (Universidad de los Andes)
So, I'm programming a c++ mini project for university. The project consists of making a draft of a software oriented to buying and selling crypto currencies, however, since yesterday I've been getting a problem with it (a segmentation fault core dumped specifically)... So, as this page had been helpful with my previous programs and this time I didn't find something that could have helped me, I decided to register and ask in case someone is willing to help me.
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
class usuario {
private :
string username[10], password[10];
int aux;
public :
usuario();
void setUnamep(string, string, int);
string getUnamep();
void setPass(string);
string getPass();
int DataAcc(string, string);
~usuario();
};
class moneda {
protected :
float cantidad;
public :
moneda(float);
void setCant(float);
void getCant();
~moneda();
};
class bitcoin : public moneda {
private :
float btc[20];
public :
bitcoin (float);
void setBuy(float, float[]);
void getBuy();
void mostrarc(float);
~bitcoin();
};
usuario::usuario () {
}
void usuario::setUnamep(string username_, string password_, int aux_) {
string PreUser[20], aux_2;
aux = aux_;
for (int i= 1; i <= aux; i++) {
username[i] = username_[i];
password[i] = password_[i];
cout<<"\nEnter an username: ";
cin>>username[i];
cout<<"Enter a password: ";
cin>>password[i];
username[0] = "."; //pass 1 leer
for (int v = 0 ; v < i; v++) {
if (username[v] == username[i]) {
cout<<"\nUsername already in use. Choose another"<<endl;
username[i] = "null";
password[i] = "null";
i--;
v = 20000;
}
}
}
}
int usuario::DataAcc(string InUs, string InPass) {
bool ing = false, ret = false;
int u = 0;
do {
if (InUs==username[u] and InPass==password[u]) {
ing = true;
u = 10;
ret = true;
}
else //////
u++;
}
while (ing == false and u<5);
if (u == 5)
cout<<"\nIncorrect user or password. Try again."<<endl;
if (ing == true) {
cout<<"\nAccount data..."<<endl;
}
return ret;
}
usuario::~usuario() {
}
moneda::moneda(float cantidad_) {
cantidad = cantidad_;
}
moneda::~moneda() {
}
bitcoin::bitcoin(float cantidad_) : moneda(cantidad_) {
}
void bitcoin::setBuy(float cantidad_, float btc_[]) {
int aux;
for (int i = 0; i < 20 ; i++) {
btc[i] = btc_[i];
}
cout<<"How many BTC do you wish to buy?: ";
cin>>cantidad;
btc[aux] = btc[aux] + cantidad;
}
bitcoin::~bitcoin() {
}
int main() {
int opc = 0, aux1;
string InUs, InPass;
int aux2 = 0;
bitcoin b1(0);
cout<<"Welcome to BitZuela 2018, down there you have several options for you to choice which one do you want to run. ";
cout<<"\n\n1. Sign Up."<<endl;
cout<<"2. Log in."<<endl;
cout<<"3. Finish program."<<endl;
usuario u1;
while (opc >=0 and opc <=2) {
cout<<"\nPress the button of the option you want to run: ";
cin>>opc;
if (opc==1) {
cout<<"\nHow many accounts do you want to register?: ";
cin>>aux1;
u1.setUnamep("null", "null", aux1);
}
if (opc==2) {
cout<<"\nUsername: ";
cin>>InUs;
cout<<"Password: ";
cin>>InPass;
aux2 = u1.DataAcc(InUs, InPass);
if (aux2 == 1) {
b1.setBuy(0,0); //The problem is when this object is created
}
}
if (opc == 3)
cout<<"\nProgram finished."<<endl;
}
return 0;
}
That's it, I would be very grateful if someone can help me solving this problem. Also, if you have a suggestion about another thing, It'll be a pleasure to read it!
There seems to be some trouble with this method
void bitcoin::setBuy(float cantidad_, float btc_[]) {
int aux;
for (int i = 0; i < 20 ; i++) {
btc[i] = btc_[i];
}
cout<<"How many BTC do you wish to buy?: ";
cin>>cantidad;
btc[aux] = btc[aux] + cantidad;
}
The 'aux' variable is used before it is set resulting in undefined behavior.
Also the call is passing a 0 instead of a float[]. The compiler interprets the 0 as a nullptr, resulting a crash in ::setBuy
if (aux2 == 1) {
b1.setBuy(0,0);
Probably some other issues but fixing these will be a step in the right direction
Your core dumped is in the setBuy function. You ask for an array of float, but when you call it in your code, you pass a "0", but you should pass an array of 20 elements.
The aux variable is set inside the function, but I think you should pass it from the signature of the function.
Also, the cantidad variable that you are using inside that function is not the one in the signature (you should remove it from the signature, or add an _ to cantidad).
I also looked into your setUnamep function, you should use an std::map for your username and password management (You can search for an already existing keys in log(n)).

strcpy is copying sth character onwards i string . How to resolve this error?

My complete code is at pastebin.
There is a train database , and user enters train number to book a ticket.The function updt_tick should copy the values of train's name,source and destination into passenger's reservation object.
But the problem is that 5th character onwards are only being copied.
Here is the function's code sample.Train database is entered by user.
void updt_tick()
{
fstream f;
f.open("train.dat",ios::in | ios::binary);
while(f.read((char*)&t,sizeof(t)))
{
if (tno==t.tno)
{
strcpy(bp,t.source);
strcpy(dest,t.dest);
strcpy(tname,t.tname);
amt=SeatNum*t.PerSeatFare;
break;
}
}
f.close();
}
The train class is ->
class train
{
public:
int tno;
char tname[100];
char source[100];
char dest[100];
int PerSeatFare;
public:
void getdetail();
void showdetail();
}t;
The reserv class is ->
`
class reserv
{
//Assume that cust select train according to his source and destination.
public:
int pnr;
int tno;
char tname[100];
char pnames[10][100];
int ages[10];
int SeatNum;
int i;
int d,m,y;
float amt;
char bp[100],dest[100];
void updt_tick()
{
fstream f;
f.open("train.dat",ios::in | ios::binary);
while(f.read((char*)&t,sizeof(t)))
{
if (tno==t.tno)
{
strcpy(bp,t.source);
strcpy(dest,t.dest);
strcpy(tname,t.tname);
amt=SeatNum*t.PerSeatFare;
break;
}
}
f.close();
}
public:
void getresdet()
{
cout<<"Enter the details as follows\n";
cout<<"Train no:";
cin>>tno;
cout<<"No of seats required:";
cin>>SeatNum;
cin.ignore();
for(i=0; i<SeatNum ; i++)
{
cout<<"Passenger name:";
gets(pnames[i]);
cout<<"Passenger age:";
cin>>ages[i];
cin.ignore();
}
cout<<"Date of travel:";
cin>>d>>m>>y;
cout<<"Details Accepted\n";
pnr=rand();
updt_tick();
}
void showresdet()
{
cout<<"Pnr no:"<<pnr;
cout<<"\nTrain no:"<<tno;
cout<<"\nTrain name:";
puts(tname);
cout<<"Boarding point:";
puts(bp);
cout<<"Destination pt:";
puts(dest);
cout<<"No of seats reserved:"<<SeatNum;
for(i=0; i<SeatNum; i++)
{
cout<<"Passenger name:";
puts(pnames[i]);
cout<<"Passenger age:"<<ages[i];
}
cout<<"\nDate of reservation:"<<d<<"-"<<m<<"-"<<y;
cout<<"\nYou must pay:"<<amt<<endl;
}
int getpnr()
{
return pnr;
}
};
Edit: There was nothing wrong with strcpy or any other code. I made
the foolish mistake of giving the file name as "train.dat" instead of
"trains.dat:.
Im not sure how did you manage to read 5 characters, because there is a problem is in your code. The file which you use to store train details is "trainS.dat", not "train.dat".

if condition used with JOptionPane showMessageDialog

The code below when run generates only the name of the last student with marks<30 I want all the names of the student to be displayed in the same message dialog box. Please help. Thanks and I'm fairly new to coding.
import javax.swing.JOptionPane;
class marks
{
public static void main(String args[])
{
String name=" ";
int marks=0;
for(int x=0; x<3; x++)
{
name=JOptionPane.showInputDialog(null,"Please enter the name");
marks=Integer.parseInt(JOptionPane.showInputDialog(null,"Please enter the marks"));
}
if (marks<30)
{
(JOptionPane.showMessageDialog(null,"the students who got marks below 30 are: "+name));
}
}
}
I think you need to read some basics. Also for that purposes use arrays instead of one variable. I change your code, I think it do what you want :
public class marks {
public static void main(String args[]) {
int count = 3;
String[] name = new String[3];
int[] marks = new int[3];
for (int x = 0; x < count; x++) {
name[x] = JOptionPane.showInputDialog(null, "Please enter the name");
marks[x] = Integer.parseInt(JOptionPane.showInputDialog(null,"Please enter the marks"));
}
String names="";
for(int i = 0;i<count;i++){
if (marks[i] < 30){
names+= name[i]+", ";
}
}
if(names.endsWith(", ")){
names = names.substring(0,names.length()-2);
}
if(!names.isEmpty()){
JOptionPane.showMessageDialog(null,"the students who got marks below 30 are: " + names);
}
}
}
import java.util.ArrayList;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
class marks
{
public static void main(String args[])
{int x=0;
// String name=" ";
// int marks=0;
ArrayList<Integer> marks= new ArrayList<Integer>();
ArrayList<String> name= new ArrayList<String>();
ArrayList<String> array = new ArrayList<String>();
for(x=0; x<3; x++)
{
name.add(JOptionPane.showInputDialog(null,"Please enter the name"));
marks.add(Integer.parseInt(JOptionPane.showInputDialog(null,"Please enter the marks")));
}
// if (marks<30)
for(x=0 ; x<name.size(); x++)
{
if(marks.get(x)<30){
array.add(name.toString());
// JOptionPane.showMessageDialog(null,"the students who got marks below 30 are: "+name.);
break;
}
}
JOptionPane.showMessageDialog(null, new JScrollPane(new JList(array.toArray())));
}
}

windows causing breaking point

I am writing a program for a class assignment on learning about pointers and memory management. Allocating memory for student and courses is necessary with the new operator in this assignment and the program seems to run properly but after it prints everything the program crashes and it says that that it has triggered a break point. Any help would be appreciated.
The error is located here but I'm not sure what it means
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
struct Student //Structs
{
string firstName, lastName, aNumber;
double GPA;
};
struct Course
{
int courseNumber, creditHours;
string courseName;
char grade;
};
Student* readStudent(); // Function Prototypes
Course* readCourseArray(int&);
void computeGPA(Student *student, Course *courseArray, int coursesTaken);
void printSummary(Student *studentPTR, Course *courseArray, int courses);
int main() //Main
{
int courses = 0;
Student *studentPTR = readStudent();
Course *coursePTR = readCourseArray(courses);
computeGPA(studentPTR, coursePTR, courses);
printSummary(studentPTR, coursePTR, courses);
delete studentPTR;
delete coursePTR;
system ("pause");
return 0;
}
Student* readStudent() // Read Student
{
Student* student = new Student;
cout<<"\nEnter students first name\n";
cin>>student->firstName;
cout<<"\nEnter students last name\n";
cin>>student->lastName;
cout<<"\nEnter students A-Number\n";
cin>>student->aNumber;
return student;
}
Course* readCourseArray(int &courses) //Read Courses
{
cout<<"\nHow many courses is the student taking?\n";
cin>>courses;
const int *sizePTR = &courses;
Course *coursePTR = new Course[*sizePTR];
for(int count = 0; count < *sizePTR; count++) //Enter course information
{
cout<<"\nEnter student "<<count+1<<"'s course name\n";
cin>>coursePTR[count].courseName;
cout<<"\nEnter student "<<count+1<<"'s course number\n";
cin>>coursePTR[count].courseNumber;
cout<<"\nEnter student "<<count+1<<"'s credit hours\n";
cin>>coursePTR[count].creditHours;
cout<<"\nEnter student "<<count+1<<"'s grade\n";
cin>>coursePTR[count].grade;
}
return coursePTR;
}
void computeGPA(Student *studentPTR, Course *courseArray, int coursesTaken) // Compute GPA
{
double total = 0, hours = 0;
for(int count = 0; count < coursesTaken; count++)
{
hours += courseArray[count].creditHours;
if (courseArray[count].grade == 'A')
total+=4;
else if (courseArray[count].grade == 'B')
total+=3;
else if (courseArray[count].grade == 'C')
total+=2;
else if (courseArray[count].grade == 'D')
total+=1;
else if (courseArray[count].grade == 'F')
total+=0;
}
studentPTR->GPA = (total / hours);
}
void printSummary(Student *studentPTR, Course *courseArray, int courses)
{
cout<<"\nReport\n";
cout<<"\nNumber Name Hours Letter Grade Point Grade";
cout<<"\n------ ---- ----- ------------ -----------\n";
for(int count = 0; count < courses; count++)
cout<<setw(3)<<courseArray[count].courseNumber<<" "<<courseArray[count].courseName<<setw(20)<<" "<<courseArray[count].creditHours<<setw(5)<<" "<<courseArray[count].grade<<endl;
cout<<"\nStudent :"<<studentPTR->firstName<<" "<<studentPTR->lastName;
cout<<"\nA-Number :"<<studentPTR->aNumber;
cout<<"\nOverall GPA :"<<studentPTR->GPA;
}
You're allocating courses with operator new[] (which is for arrays), but freeing it with operator delete, instead of operator delete[].
You should deallocate it like that:
delete[] coursePTR;
I also don't understand why you use the sizePTR pointer instead of directly using courses.
BTW, just so you'd know, this is not a 'find my bug' site. You have a code review site for that.
You need to change
delete coursePTR;
to
delete [] coursePTR;
new always needs to be used with delete, and new [] with delete [], otherwise bad things happen.