C++ Console Application1.exe has triggered a breakpoint - c++

when I try to set
cub.SetArray(cube);
I get an error
Console Application1.exe has triggered a breakpoint
What I'm doing wrong? When I try to debug cub -> cubesarray I get size -842150451. I don't understand why.Here's my all code
class Cube{
public:
static const int Change_ARRAY = 5;
private:
string color;
int size;
int *walls;
int n; // current size of array
int maximumsize; // maximum size of array
void Increase(int many);
public:
Cube(int maximumsize = 0);
~Cube();
void SetWalls(int wall);
void SetColor(string color);
void SetSize(int size);
string GetColor(){return color;}
int GetWalls(int i){return walls[i];}
int GetSize(){return size;}
int GetN(){return n;}
};
Cube::Cube(int maximumsize):n(0), maximumsize(maximumsize), size(size), walls(NULL){
if(maximumsize > 0){
walls = new int[maximumsize];
}
}
Cube::~Cube(){
if(walls){
delete [] walls;
}
}
void Cube::Increase(int many){
if(many > maximumsize){
int *newest = new int[many];
for(int i=0; i<n; i++)
newest[i] = walls[i];
delete [] walls;
walls = newest;
maximumsize = many;
}else if( many < maximumsize){
int *newest = new int[many];
for(int i=0; i<many; i++)
newest[i] = walls[i];
delete [] walls;
walls = newest;
n = maximumsize = many;
}
}
void Cube::SetWalls(int wall){
if(n == maximumsize) Increase(n + Change_ARRAY);
walls[n] = wall;
n++;
}
void Cube::SetColor(string color){
this->color = color;
}
void Cube::SetSize(int size){
this->size = size;
}
class CubesArray{
public:
static const int Change_Array = 5;
private:
Cube *cubesarray;
int currentsize; // current size of array
int maxsize; // maximumsize
void Change (int kk);
public:
CubesArray(int maxsize = 1);
~CubesArray();
void SetArray(Cube c);
Cube GetArray(int ind){return cubesarray[ind];}
int GetCsize(){return currentsize;}
};
CubesArray::CubesArray(int maxsize):cubesarray(NULL), currentsize(0), maxsize(maxsize){
if(maxsize > 0){
cubesarray = new Cube[maxsize];
}
}
CubesArray::~CubesArray(){
if(cubesarray){
delete [] cubesarray;
}
}
void CubesArray::Change(int kk){
if(kk > maxsize){
Cube *newarr = new Cube[kk];
for(int i=0; i<currentsize; i++)
newarr[i] = cubesarray[i];
delete [] cubesarray;
cubesarray = newarr;
maxsize = kk;
}if(kk < maxsize){
Cube *newarr = new Cube[kk];
for(int i=0; i<kk; i++)
newarr[i] = cubesarray[i];
delete [] cubesarray;
cubesarray = newarr;
currentsize = maxsize = kk;
}
}
void CubesArray::SetArray(Cube cub){
if(currentsize = maxsize) Change(currentsize + Change_Array);
cubesarray[currentsize] = cub;
currentsize++;
}
void Read(CubesArray & cub);
int main(){
CubesArray cub;
Read(cub);
system("pause");
return 0;
}
void Read(CubesArray & cub){
string color;
int size;
int i=0;
Cube cube;
ifstream fd(Data);
while(!fd.eof()){
fd >> color >> size;
cube.SetSize(size);
cube.SetColor(color);
cout << cube.GetColor() << " " << cube.GetSize() << " ";
while(fd.peek() != '\n' && !fd.eof()){
int w;
fd >> w;
cube.SetWalls(w);
cout << cube.GetWalls(i) << " ";
cub.SetArray(cube); // when I set cube to cub I get this error!!!
i++;
}
cout << endl;
fd.ignore();
}
}

Change:
if(currentsize = maxsize)
To:
if(currentsize == maxsize)
In addition, here is your real problem:
You have no copy-constructor in class Cube, so the walls array is not properly copied whenever you send a Cube instance by value, e.g., cub.SetArray(cube).
You must define it as follows:
Cube::Cube(const Cube& cube):n(cube.n),maximumsize(cube.maximumsize),size(cube.size),wall(NULL)
{
if (maximumsize > 0)
{
walls = new int[maximumsize];
for (int i=0; i<maximumsize; i++)
wall[i] = cube.wall[i];
}
}
And you have no assignment-operator in class Cube, so the walls array is not properly copied whenever you assign one Cube instance into another, e.g., cubesarray[currentsize] = cub.
You must define it as follows:
Cube& Cube::operator=(const Cube& cube)
{
n = cube.n;
maximumsize = cube.maximumsize;
size = cube.size;
wall = NULL;
if (maximumsize > 0)
{
walls = new int[maximumsize];
for (int i=0; i<maximumsize; i++)
wall[i] = cube.wall[i];
}
return *this;
}
BTW, in the copy-constructor, you can simply call the assignment-operator (remove coding redundancy):
Cube::Cube(const Cube& cube)
{
if (this != &cube)
*this = cube;
}

Your Cube class violates the rule of three. Look here:
void CubesArray::SetArray(Cube cub){ // calls copy constructor
That call creates a copy of your Cube class. Your Cube class is not safely copyable. Please see this and scroll down to the Managing Resources section: What is The Rule of Three?
You should pass Cube by reference or const reference, not by value. Doing so may correct the error you're having now, but still, your class is faulty.

Related

Dynamic Array resizing in C++ Doesn't work properly

i have this reSize function in my Array header
void reSize(int newsize) {
T* old = items;
size = newsize;
items = new T[newsize];
for (int i = 0;i < length;i++)
items[i] = old[i];
delete[]old;
}
and my main code:
struct User{
string name;
Array<int> data;
};
int main() {
Array<User> x(3);
x.get(0).name = "Kmal";
x.get(0).data.push_back(2); x.get(0).data.push_back(3);
x.reSize(10);
cout << x.get(0).data.get(0) <<endl;
return 0;
}
the problem is after resizing, my values that were stored in "data" variable are gone.
when i commented the code.
//delete[] old
in the reSize function
it worked fine...so i guess the problem is when i delete the pointer it deletes also the pointer inside the struct object which i don't want it to happen..
i don't want to comment the command becuz a leak in the memory will happen...how to fix this problem ?.
Update: My Array Class .
#include <iostream>
using namespace std;
template <class T>
class Array {
private :
T* items;
int size;
int length;
public :
Array() {
this->size = 0;
items = new T[this->size];
length = 0;
}
Array(int size) {
this->size = size;
items = new T[this->size];
length = 0;
}
int getsize() {
return this->size;
}
template <class T> void push_back(T x) {
if ((length+1) <= size) {
items[length] = x;
length++;
}
else {
this->reSize(size+1);
items[length] = x;
length++;
}
}
template <class T> void Insert(int index, T x) {
if (length + 1 <= size) {
for (int i = length;i > index;i--) {
items[i] = items[i - 1];
}
items[index] = x;
length++;
}
else {
this->reSize(size+1);
for (int i = length;i > index;i--) {
items[i] = items[i - 1];
}
items[length] = x;
length++;
}
}
template <class T> int Find(T x) {
int index = -1;
for (int i = 0;i < length;i++) {
if (items[i] ==x) {
index = i;
break;
}
}
return index;
}
void remove(int index) {
items[index] = "";
if(index+1 < length)
for (int i = index;i < length-1;i++) {
items[i] = items[i + 1];
items[i + 1] = "";
}
length--;
}
void reSize(int newsize) {
T* old = items;
size = newsize;
items = new T[newsize];
for (int i = 0;i < length;i++)
items[i] = old[i];
delete[]old;
}
void Merge(Array<T> x){
T* old = items; int oldlength = length;
items = new T[size + x.size];
size = size + x.size;
length += x.length;
for (int i = 0;i < length;i++) {
if(i< oldlength)
items[i] = old[i];
else
items[i] = x.items[i-oldlength];
}
delete[] old;
}
T& get(int index) {
return items[index];
}
}
struct User{
string name;
Array<int> data;
};
int main() {
Array<User> x(3);
// this line causes some problems
x.get(0).name = "Kmal";
x.get(0).data.push_back(2); x.get(0).data.push_back(3);
x.reSize(10);
cout << x.get(0).data.get(0) <<endl;
return 0;
}
In your code, declaring Array<User> x(3) declares an empty array with 3 elements that are preallocated. The length property of the array is 0. When the array is copied, length(0) elements are copied over into the resized storage. When you access the 0th element, it won't be copied on resize. What you actually need to do is call push_back() to add an element to the array so that length becomes 1 and the element is copied on resize.
Also, your array class is lacking a proper copy constructor and move constructor, which means copying it won't work at all. This means that User cannot be copied properly since it contains an array, which means that resizing an array of User won't work. You need to implement a copy constructor and copy assignment operator to be able to copy the array. You also need a destructor since, right now, the array is leaking memory when it goes out of scope.

I have a weird segmentation fault, std::length_error and sometimes my code works?

I finished some code that prints out how many times a word shows up. However, when I finished and tried to run the code on a different compiler it did not work. Firstly, here is a picture of my code working on my initial file:
But when I used a different compiler (onlinegdb) I get this error:
The thing that confused me the most is; when I try and replicate the file into a new VS Code .cpp file, it does not work. It runs the code but then prints out nothing. When I went into gdb I find this error:
If anyone knows where the segmentation fault/std::length_error are happening at please let me know, and if you have any recommendations that would be great! Also, knowing why I get different results on the same compiler (VS Code) would also be helpful. Here is my code:
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
class WordOccurrence
{
public:
WordOccurrence(const string& word="", int num=1)
{
word_ = word;
num_ = num;
}
bool matchWord(const string & compare)
{
if(word_ == compare)
return true;
else
return false;
}
void increment()
{
num_++;
}
string getWord() const
{
return word_;
}
int getNum() const
{
return num_;
}
private:
string word_;
int num_;
};
class WordList
{
public:
friend bool equal(const WordList&, const WordList&);
WordList();
WordList(const WordList &);
~WordList();
WordList operator= (const WordList &);
void addWordFile(WordList w);
void addWord(const string &);
void print();
private:
WordOccurrence *wordArray_;
int size_;
};
WordList::WordList()
{
size_ = 0;
wordArray_ = new WordOccurrence [size_];
}
WordList::WordList (const WordList &neww)
{
size_ = neww.size_;
wordArray_ = new WordOccurrence[size_];
for (int i = 0; i <= (size_ - 1); i++)
wordArray_[i] = neww.wordArray_[i];
}
WordList::~WordList ()
{
delete [] wordArray_;
}
WordList WordList::operator= (WordList const &overload)
{
WordList temp(overload);
swap(wordArray_, temp.wordArray_);
swap(size_, temp.size_);
return *this;
}
void WordList::addWord(const string& word)
{
if(size_ == 0)
{
WordOccurrence *first_array = new WordOccurrence[1];
first_array[0] = word;
delete[] wordArray_;
wordArray_ = first_array;
delete[] first_array;
size_++;
return;
}
//if the word is already in the array, we increase the count of it by 1
for (int i = 0; i < size_; i++)
{
if (wordArray_[i].matchWord(word))
{
wordArray_[i].increment();
return;
}
}
//if it is not in the array already, we need to increase its size and then add the new word to the wordarray.
WordOccurrence *new_array = new WordOccurrence[size_+1];
for (int i = 0; i < size_; i++)
{
new_array[i] = wordArray_[i];
}
new_array[size_] = WordOccurrence(word);
delete[] wordArray_;
size_++;
wordArray_ = new_array;
delete[] new_array;
}
void WordList::print()
{
//to output to a file because when we get a lot of words it's kinda hard to see on just the terminal
ofstream myfile ("output.txt");
WordList sortedList(*this);
//Sorting from smallest to largest
int smallest = wordArray_[0].getNum();
for (int i = 1; i < size_; i++)
{
//stores the smallest value into smallest
if(wordArray_[i].getNum() < smallest)
smallest = wordArray_[i].getNum();
}
int location = 0;
//stores values from start to finish in the new list starting at location sortedList[0]
while(location < size_)
{
for(int i = 0; i < size_; i++)
{
//runs through the new list until it finds a value that is apart of the smallest/rarest words
if(wordArray_[i].getNum() == smallest)
{
sortedList.wordArray_[location] = wordArray_[i];
location++;
}
}
//increases the value of smallest allowing for numbers with greater found values to be sorted
smallest++;
}
//prints out the sorted version of wordarray
for(int i = 0; i < size_; i++)
{
string word = sortedList.wordArray_[i].getWord();
int count = sortedList.wordArray_[i].getNum();
cout << "Word: " << word << " Amount: " << count << endl;
//for longer amounts of text, it was hard to see on a editor so I also have it out to a file.
myfile << "Word: " << word << " Amount: " << count << endl;
}
}
int main()
{
WordList w;
w.addWord("one");
w.addWord("one");
w.addWord("two");
w.addWord("three");
w.addWord("four");
w.addWord("four");
w.addWord("four");
w.addWord("four");
w.addWord("five");
w.addWord("five");
w.addWord("five");
cout << "Sorted list" << endl;
w.print();
}
This is bugged
WordOccurrence *first_array = new WordOccurrence[1];
first_array[0] = word;
delete[] wordArray_;
wordArray_ = first_array;
delete[] first_array;
size_++;
return;
You assign first_array to wordArray_ and then you delete it. This leaves wordArray_ as an invalid pointer. Just remove delete[] first_array;. Two deletes and only one new should have been a clue that something was wrong.
Same bug later on in the same function
WordOccurrence *new_array = new WordOccurrence[size_+1];
for (int i = 0; i < size_; i++)
{
new_array[i] = wordArray_[i];
}
new_array[size_] = WordOccurrence(word);
delete[] wordArray_;
size_++;
wordArray_ = new_array;
delete[] new_array;
delete[] new_array; should not be there.

Why is the overloading operator "=" not working properly on my class for Dynamic Arrays? C++

I'm trying to work with dynamic arrays. When I try to overload the "=" operator it does not work. When debugging the file it doesn't execute the void function to overload the operator.
#include <iostream>
using namespace std;
class cppArray {
public:
cppArray(int size);
~cppArray();
int read(int index);
void write(int content, int index);
void operator=(cppArray& s);
int search(int target);
int size();
private:
int* myArray;
int arraySize;
};
cppArray::cppArray(int size) {
myArray = new int[size];
arraySize = size;
}
//delete the memory space assigned to myArray
cppArray::~cppArray() {
delete[] myArray;
myArray = 0;
}
int cppArray::read(int index) {
if (index < arraySize) {
return myArray[index];
}
else {
cout << "Out of range" << endl;
exit(1);
}
}
Here I'm trying to copy the content of the original array to an auxiliar one, and then redefine the size of the original array so I can add more content to the original array
void cppArray::write(int content, int index) {
if (index < arraySize) {
myArray[index] = content;
}
else {
cppArray auxArray(arraySize);
auxArray.myArray = myArray;
delete[] myArray;
arraySize = index + 1;
myArray = new int[arraySize];
myArray = auxArray.myArray;
myArray[index] = content;
}
}
I'm pretty sure this is wrong, but I can't figure out a way to overload it correctly
void cppArray::operator=(cppArray& s) {
delete[] s.myArray;
s.myArray = new int[arraySize];
for (int i = 0; i < arraySize; i++)
{
myArray[i] = s.myArray[i];
}
}
int cppArray::size() {
return arraySize;
}
int main(int argc, char** argv) {
cppArray dsArray(3);
dsArray.write(1, 0);
dsArray.write(2, 1);
dsArray.write(3, 2);
dsArray.write(4, 3);
for (int i = 0; i < dsArray.size(); i++) {
cout << dsArray.read(i) << "\t";
}
cout << endl;
return 0;
}```
Your implementation is almost correct, but you delete the wrong array. You should only modify *this object, and not s. Also, you should follow conventions, or people will be very surprised when using your class.
Here's corrected version:
//return *this - a very expected convention
cppArray& cppArray::operator=(const cppArray& s) {
// Make sure s is not modified ^^^^
if (this == &s) {
return *this; //protection against self writing, things would get bad if you did that
}
arraySize = s.arraySize; //copy size first
delete[] myArray; //delete array from this object
myArray = new int[arraySize]; //recreate array
for (int i = 0; i < arraySize; i++)
{
myArray[i] = s.myArray[i]; //no changes here
}
return *this;
}

Terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc. Improper dynamic allocation?

I am attempting to create a class of MovieList that contains a dynamically allocated double [] of weeklyRevenue. I keep getting this error, I know it is associated with memory allocation, but not sure about the specifics. How can I fix this?
class Movie
{
public:
Movie();
void setMovieData(char [],char [],char, int,int,int,int,double[]);
~Movie();
string getTitle() const;
char getGenre() const;
void display() const;
double getBoxOffice();
private:
char title[75];
char director[50];
char genre;
Date releaseDate;
double* weeklyRevenue;
double* weeklyTake;
int numWeeks;
};
class MovieList
{
public:
MovieList(); //constuctor
~MovieList(); //deconstructor
int getCapacity();
int getCurrentSize();
void addMovie(char[], char[], char, int ,int, int,int, double[]);
void insertMovie(Movie, int);
void deleteMovie(char []);
void displayList() const;
void displayByGenre(char) const;
int search(char []) const;
Movie* movieListObj;
private:
int capacity, currentSize;
}
movieList.cpp:
void Movie::setMovieData(char t[], char dir[], char g, int month, int day, int year,int numWks, double wklyTake[])
{
for(int i =0; i < 75; i++)
title[i] = t[i];
for (int i = 0; i < 50; i++)
director[i] = dir[i];
genre = g;
releaseDate.setDate(month,day,year);
numWeeks = numWks;
weeklyRevenue = new double[numWeeks];
wklyTake = new double[numWeeks];
for (int i = 0; i < numWeeks; i++)
weeklyRevenue[i] = wklyTake[i];
}
Movie::~Movie()
{
delete [] weeklyTake;
weeklyTake = NULL;
delete [] weeklyRevenue;
weeklyRevenue = NULL;
}
void Movie::display() const
{
cout<<"Title: ";
for(int i =0; i < 75; i++)
cout<< title[i];
cout << "\nDirector: ";
for (int i = 0; i < 50; i++)
cout << director[i];
cout << "\nGenre:" << genre<<endl;
cout << "Release Date: ";
releaseDate.print();
cout<<"Weeks since Release: " << numWeeks<<endl;
cout <<"Box office: " ;
double BoxOffice = 0;
for(int i =0; i <numWeeks; i++)
BoxOffice += weeklyRevenue[i];
cout << BoxOffice;
}
MovieList::MovieList()
{
capacity = 5;
currentSize = 0;
movieListObj = new Movie[currentSize];
}
MovieList::~MovieList()
{
delete [] movieListObj;
movieListObj = NULL;
}
void MovieList::addMovie(char t[], char dir[], char g, int month, int day, int year, int numWeeks, double* weeklyRevenue)
{
if( currentSize >= capacity)
{
capacity += 5;
}
movieListObj[currentSize].setMovieData(t, dir, g, month, day, year, numWeeks, weeklyRevenue);
currentSize++;
}
void MovieList::insertMovie(Movie movieList, int position)
{
if(position < 0 || position > capacity)
cout << "insert failed";
else
{
movieListObj[position] = movieList;
cout << "Insert successful";
}
}
void MovieList::deleteMovie(char titleDel[])
{
for( int i= 0; i < currentSize; i++)
{
while( titleDel == movieListObj[i].getTitle())
cout<< "Delete" ;
}
}
I am attempting to add a movie, but once I enter all data in the addMovie function I get the error "terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Abort"

Am I using delete[] operator correctly?

This is my code:
linearMatrix lAmatrixmatrixmult(const linearMatrix &A,
const linearMatrix &B)
{
//Local variables
int W_A = A.Get_Width;
int H_A = A.Get_Height;
int H_B = B.Get_Height;
int W_B = B.Get_Width;
float *vectorA;
float *vectorB;
float *vectorC;
//================
//Memory allocation
try{
vectorA = new float[W_A * H_A];
}
catch(bad_alloc &ex)
{
cerr << "Exception:" << ex.what();
exit(1);
}
try{
vectorB = new float[W_B * H_B];
}
catch(bad_alloc &ex)
{
cerr << "Exception:" << ex.what();
exit(1);
}
try{
vectorC = new float[W_A * H_B];
}
catch(bad_alloc &ex)
{
cerr << "Exception:" << ex.what();
exit(1);
}
//=================
//Initialization
vectorA = A.Get_Vector;
vectorB = B.Get_Vector;
//==============
if(W_A == H_B)
{
linearMatrix C(W_A, H_B);
for(int i = 0; i < W_A; i++)
{
for(int j = 0; j < W_B; j++)
{
float sum = 0;
for(int k = 0; k < W_A; k++)
{
float a = vectorA[i * W_A + k];
float b = vectorB[k * H_B + j];
sum += a * b;
}
vectorC[i * W_A + j] = sum;
}
}
C.Set_Vector(vectorC, W_A, H_B);
//Free memory
delete [] vectorA;
delete [] vectorB;
delete [] vectorC;
//===========
return C;
}
else
{
cout << "Different sizes! Cannot perform mmmult" << endl;
//Free memory
delete [] vectorA;
delete [] vectorB;
delete [] vectorC;
//===========
exit(1);
}
}
And the ~linearMatrix is:
//Destructor definition
linearMatrix::~linearMatrix()
{
delete [] myVector;
}
Where linearMatrix is:
class linearMatrix
{
public:
//Constructor
linearMatrix(const int Width, const int Heigth);
//Copy constructor
linearMatrix(const linearMatrix &that);
//Copy assignment operator
linearMatrix& operator=(const linearMatrix& that);
//Destroyer
~linearMatrix();
//We read a matrix file
void Read_File_Matrix(const char *Path);
//We write a matrix file
void Write_File_Matrix(const char *Path);
//Generate a diagonal dominant matrix
void Generate_Diagonal_Dominant(void);
//Generate a random matrix
void Generate_Random_Matrix(void);
//Set a float *vector
void Set_Vector(const float *V, const int Width, const int Heigth);
//Show a little vector
void Show_Little_Matrix(void);
//Get the vector
//Suppose V is previously allocated
float *Get_Vector(void);
//Get total number of elements
int Get_NumberofElements(void);
//Get Width
int Get_Width(void);
//Get Height
int Get_Height(void);
private:
int myWidth, myHeight; // Width and Height
float* myVector;
//Aux function for testing
bool Test_Sizes(const int Width, const int Heigth);
};
Must I free memory before leaving a function if I used the new operator inside a function? Should I free memory before any exit() call?
No, that is not correct:
vectorA = new float[W_A * H_A]; // allocates memory
vectorA = A.Get_Vector(); // allocated memory is leaked
// vectorA now points to memory owned by A
delete [] vectorA; // delete memory owned by A
Of course, in C++ you would normally just use std::vector<float>.