c++ function can not call twice - c++

I have this code. From main function i twice call sportPrisevinners function and if it is first call of this function it works correctly and I recive correct result, but when i call it second time I recive incorrect result even I pass this function with same arguments. Please help me to solve this problem while it doesn`t make me crasy.
const char* countries[] = {"ru", "gb", "us", "uk", "ch", "de"};
const int countriesCount = 6;
const char* sports[] = {"runing", "swiming", "baseball", "football", "jumping", "kerling"};
const int sportsCount = 6;
enum {
Empty = 0,
Bronse,
Silver,
Gold
};
struct member {
char sport[9];
char country[3];
int points;
int medal;
};
struct members {
member* list;
int count;
};
string medalToStr(int medal)
{
switch (medal) {
case Gold:
return "Gold";
case Silver:
return "Silver";
case Bronse:
return "Bronse";
default:
return "Empty";
}
}
void printMembers(members &list)
{
for (int i = 0; i < list.count ; i++)
cout << /*i << " " <<*/ medalToStr(list.list[i].medal) << " in "
<< list.list[i].sport << " with " << list.list[i].points
<< " from " << list.list[i].country << endl;
}
void generate()
{
ofstream file("members.dat", ios::binary|ios::trunc);
member temp;
for (int i = 0; i < sportsCount ; i++)
for (int j = 0; j < countriesCount ; j++)
{
int count = rand()%5+5;
for (int k = 0; k < count ; k++)
{
strcpy(&temp.sport[0], sports[i]);
strcpy(&temp.country[0], countries[j]);
temp.points = rand()%100;
temp.medal = Empty;
file.write((char*)&temp, sizeof(member));
}
}
file.close();
}
members sportPrisevinners(const char* sport)
{
//reading
ifstream file("members.dat", ios::binary);
member* loaded = new member[60];
int pos = 0;
while (!file.eof())
{
member temp;
file.read((char*)&temp, sizeof(member));
static bool reading = false;
if (strncmp(&temp.sport[0], sport, strlen(sport))==0) {
reading = true;
loaded[pos++] = temp;
} else if (reading) {
break;
}
}
file.close();
//sorting
int count = 3;
for (int i = 0; i < pos-1 ; i++)
{
for (int j = i+1; j < pos ; j++)
if (loaded[i].points<loaded[j].points)
{
member temp = loaded[i];
loaded[i] = loaded[j];
loaded[j] = temp;
}
if (i<count) {
static int last = -1;
if (loaded[i].points==last)
count++;
loaded[i].medal = count-i;
last = loaded[i].points;
} else break;
}
//returning
members result;
result.list = new member[count];
memcpy(result.list, loaded, count*sizeof(member));
/*for (int i = 0; i < count; i++)
result.list[i] = loaded[i];*/
result.count = count;
delete[] loaded;
return result;
}
int main(int /*argc*/, char */*argv*/[])
{
srand(time(0));
generate();
members r = sportPrisevinners(sports[4]);
printMembers(r);
delete[] r.list;
members l = sportPrisevinners(sports[5]);
printMembers(l);
delete[] l.list;
system("pause");
return 0;
}

I suspect it's the static local variables in your function. They won't have the same values on each call to the function, and this could affect the results. The initialization of these variables is performed just once - the first time they come into scope - so each subsequent time the function is called, you pick up the values these variables had last time the function ran.

Related

can't figure out where the heap overwriting is

#include<iostream>
using namespace std;
class Text{
public:
~Text(){
delete data;
}
char* data{};
int mSize{};
void fill(char* stringInput) {
mSize = strlen(stringInput);
data = new char [mSize];
for (int i = 0; i < mSize; i++){
data[i] = stringInput[i];
}
}
};
class myString{
public:
explicit myString(int size){ // constructor
strAmount = size;
strings = new Text [size];
}
~myString(){ // destructor
delete[] strings;
}
void addString(char* input){
strings[filledAmount].fill(input);
filledAmount++;
}
void delString(int pos){
for ( int i = pos; i < filledAmount; i++){
swap(strings[i], strings[i+1]);
}
strings[filledAmount].data = nullptr;
strings[filledAmount].mSize = 0;
filledAmount--;
}
void eraseEverything(){
for ( int i = 0; i < filledAmount; i++){
strings[i].data = {};
strings[i].mSize = 0;
}
filledAmount = 0;
}
int maxString() const {
int index{};
for ( int i = 0 ; i < filledAmount; i++){
if (strings[i].mSize > strings[index].mSize){
index = i;
}
}
return index;
}
int charAmount(){
int counter{};
for(int i = 0 ; i < filledAmount; i++){
counter+=strings[i].mSize;
}
return counter;
}
double digitPercentage(){
int digitsAmount{};
for(int i = 0; i < filledAmount; i++){
for ( int j = 0; j < strings[i].mSize; j++){
if (isdigit(strings[i].data[j])){
digitsAmount++;
}
}
}
double digitPercent = (digitsAmount/(double)charAmount())*100;
return digitPercent;
}
int filledAmount{};
int strAmount{};
Text* strings;
};
void render_text(myString& obj) {
for (int k = 0; k < obj.filledAmount; k++) {
for (int i = 0; i < obj.strings[k].mSize; i++)
cout << obj.strings[k].data[i];
cout << endl;
}
cout << endl;
}
int main(){
myString a(5);
a.addString((char *) "zxc 1v1 forever shadow fiend");
a.addString((char *) "This is a string");
a.addString((char *) "12345");
a.addString((char *) "Hello");
a.addString((char *) "A1oha Dance");
render_text(a);
a.delString(1);
render_text(a);
int maxInd = a.maxString();
cout << "Max string :\n";
for (int i = 0; i < a.strings[maxInd].mSize; i++) {
cout << a.strings[maxInd].data[i];
}
cout << "\n\n";
}
Please help me find the crash point. I suppose it crashes in the destructor pole, but I still can't figure it out.
This is something like a self-written string class, the problem is that I can't find the place where the problems start.
I also have a thought that the destructor tries to delete too much memory from the heap so the compiler prevents it from doing that. Can I somehow change the size of the strings array?
I have fixed all your memory errors, with the help of address sanitizers
The main change here is:
Add copy constructors and copy assignment operators
Manually delete the last element in the function delString
Though that the code now works, it's not a true modern c++ style code. I highly recommend that your using std::string to replace your Text class. Use std::vector to replace the dynamic array. Then you will stay away from the pain of memory errors. The delString should be replaced with vector::erase,which is much neat than your hand write algorithm.
https://en.cppreference.com/w/cpp/string/basic_string
https://en.cppreference.com/w/cpp/container/vector
I strongly recommend rewriting the code with std::string and std::vector
#include <cstring>
#include <iostream>
using namespace std;
class Text {
public:
~Text() { delete[] data; }
char* data{};
int mSize{};
Text() = default;
Text(const Text& oth) {
mSize = oth.mSize;
data = new char[mSize];
std::copy(oth.data, oth.data + oth.mSize, data);
}
Text& operator=(const Text& oth) {
delete[] data;
mSize = oth.mSize;
data = new char[mSize];
std::copy(oth.data, oth.data + oth.mSize, data);
return *this;
}
void fill(char* stringInput) {
mSize = strlen(stringInput) + 1;
data = new char[mSize];
for (int i = 0; i < mSize; i++) {
data[i] = stringInput[i];
}
}
};
class myString {
public:
explicit myString(int size) { // constructor
strAmount = size;
strings = new Text[size];
}
myString(const myString& oth) {
strAmount = oth.strAmount;
strings = new Text[oth.strAmount];
for (size_t i = 0; i < strAmount; ++i) {
strings[i] = oth.strings[i];
}
}
myString& operator=(const myString& oth) {
delete[] strings;
strAmount = oth.strAmount;
strings = new Text[oth.strAmount];
for (size_t i = 0; i < strAmount; ++i) {
strings[i] = oth.strings[i];
}
return *this;
}
~myString() { // destructor
delete[] strings;
}
void addString(char* input) {
strings[filledAmount].fill(input);
filledAmount++;
}
void delString(int pos) {
for (int i = pos; i < filledAmount; i++) {
swap(strings[i], strings[i + 1]);
}
delete[] strings[filledAmount].data;
strings[filledAmount].data = nullptr;
strings[filledAmount].mSize = 0;
filledAmount--;
}
void eraseEverything() {
for (int i = 0; i < filledAmount; i++) {
strings[i].data = {};
strings[i].mSize = 0;
}
filledAmount = 0;
}
int maxString() const {
int index{};
for (int i = 0; i < filledAmount; i++) {
if (strings[i].mSize > strings[index].mSize) {
index = i;
}
}
return index;
}
int charAmount() {
int counter{};
for (int i = 0; i < filledAmount; i++) {
counter += strings[i].mSize;
}
return counter;
}
double digitPercentage() {
int digitsAmount{};
for (int i = 0; i < filledAmount; i++) {
for (int j = 0; j < strings[i].mSize; j++) {
if (isdigit(strings[i].data[j])) {
digitsAmount++;
}
}
}
double digitPercent = (digitsAmount / (double)charAmount()) * 100;
return digitPercent;
}
int filledAmount{};
int strAmount{};
Text* strings = nullptr;
};
void render_text(myString& obj) {
for (int k = 0; k < obj.filledAmount; k++) {
for (int i = 0; i < obj.strings[k].mSize; i++)
cout << obj.strings[k].data[i];
cout << endl;
}
cout << endl;
}
int main() {
myString a(6);
a.addString((char*)"zxc 1v1 forever shadow fiend");
a.addString((char*)"This is a string");
a.addString((char*)"12345");
a.addString((char*)"Hello");
a.addString((char*)"A1oha Dance");
render_text(a);
a.delString(1);
render_text(a);
int maxInd = a.maxString();
cout << "Max string :\n";
for (int i = 0; i < a.strings[maxInd].mSize; i++) {
cout << a.strings[maxInd].data[i];
}
cout << "\n\n";
return 0;
}

I get Abort(core dumped) error when I try and compile the code

I have four parts to this code. One of them is a DVD class and the others are HarryPotterDVD.h, HarryPotterDVD.cpp and HarryPotterDVDDriver.cpp. When I compile the code, it compiles without giving me any errors whatsoever, but when I try to run the compiled executable, I get an Abort(core dumped) error. I think it is because of the way I used the inherited functions. Could you guys please help me figure out how to solve the problem.
DVD.cpp
#include "DVD.h"
DVD::DVD() {
id =0;
title = new char[1];
title[0] = '\0';
director = new char[1];
director[0] = '\0';
}
DVD::DVD(unsigned int i, const char* t, const char* dir) {
id = i;
int len;
for(len = 0; t[len] !='\0'; ++len);
title = new char[len+1];
for(int i = 0; i < len+1; i++) {title[i]=t[i];}
int len2;
for(len2=0; dir[len2] !='\0'; ++len2);
director = new char[len2+1];
for(int j = 0; j<len2+1; j++) {director[j] = dir[j];}
}
DVD::DVD(const DVD &d): id(d.id) {
int len;
for(len=0; d.title[len] !='\0'; ++len);
title = new char[len+1];
for(int j = 0; j < len+1; j++) {
title[j] = d.title[j];
}
int len2;
for(len2=0; d.director[len2] != '\0'; ++len2);
director = new char[len2+1];
for(int j = 0; j<len2 +1; j++) {
director[j] = d.director[j];
}
}
DVD::~DVD() {
if (title) {
delete [] title;
}
if (director) {
delete [] director;
}
}
int DVD::getID() {
return id;
}
char* DVD::getTitle() {
return title;
}
char* DVD::getDirector() {
return director;
}
void DVD::display() {
cout << '[' << id << '.' << ' ' << title << '/' << director << ']' << endl;
}
void DVD::setID(unsigned int i) {
id = i;
}
void DVD::setTitle(const char* t) {
delete [] title;
int len;
for(len = 0; t[len] !='\0'; ++len);
title = new char[len+1];
for(int i = 0; i < len+1; i++) {title[i]=t[i];}
}
void DVD::setDirector(const char* dir) {
delete [] director;
int len2;
for(len2=0; dir[len2] !='\0'; ++len2);
director = new char[len2+1];
for(int j = 0; j<len2+1; j++) {director[j] = dir[j];}
}
DVD& DVD::operator= (const DVD& arg) {
id = arg.id;
int len;
for(len = 0; arg.title[len] !='\0'; ++len);
title = new char[len+1];
for(int i = 0; i < len+1; i++) {title[i]=arg.title[i];}
int len2;
for(len2=0; arg.director[len2] !='\0'; ++len2);
director = new char[len2+1];
for(int j = 0; j<len2+1; j++) {director[j] = arg.director[j];}
return *this;
}
HarryPotterDVD.h
#ifndef _HarryPotterDVD_
#define _HarryPotterDVD_
#include<iostream>
#include "DVD.h"
using namespace std;
class HarryPotterDVD : public DVD {
int episode;
char * antagonist;
public:
HarryPotterDVD(unsigned int i, char* t, char* dir, int n, char* ant);
HarryPotterDVD();
HarryPotterDVD(HarryPotterDVD& d);
~HarryPotterDVD();
int getEpisode();
char* getAntagonist();
void display();
void setEpisode(unsigned int e);
void setAntagonist(const char* c);
HarryPotterDVD& operator= (HarryPotterDVD& arg);
};
#endif
HarryPotterDVD.cpp
#include "HarryPotterDVD.h"
#include<iostream>
using namespace std;
HarryPotterDVD::HarryPotterDVD(unsigned int i, char* t, char* dir, int n, char* ant): DVD( i , t , dir) {
episode = n;
int len;
for(len = 0; ant[len] !='\0'; ++len);
antagonist = new char[len+1];
for(int j = 0; j < len+1; j++) {antagonist[j]=ant[j];}
}
HarryPotterDVD::HarryPotterDVD(HarryPotterDVD &d) {
DVD::setID(d.DVD::getID());
DVD::setTitle(d.DVD::getTitle());
DVD::setDirector(d.DVD::getDirector());
episode = d.episode;
int len;
for(len = 0; d.antagonist[len] != '\0'; len++);
antagonist = new char[len + 1];
for(int i = 0; i < len; i++){
antagonist[i] = d.antagonist[i];
}
antagonist[len+1] = '\0';
}
HarryPotterDVD::HarryPotterDVD() {
episode = -1;
char* tmp = "";
antagonist = tmp;
}
HarryPotterDVD::~HarryPotterDVD(){
delete [] antagonist;
}
int HarryPotterDVD::getEpisode(){
return episode;
}
char * HarryPotterDVD::getAntagonist(){
return antagonist;
}
void HarryPotterDVD::display(){
cout << "[" << DVD::getID() << ". HP" << episode;
cout << ":" << DVD::getTitle() << "/" << DVD::getDirector();
cout << "/" << antagonist << "]" << endl;
}
void HarryPotterDVD::setEpisode(unsigned int e){
episode = e;
}
void HarryPotterDVD::setAntagonist(const char * c){
delete [] antagonist;
int len;
for(len = 0; c[len] != '\0'; len++);
antagonist = new char[len + 1];
for(int i = 0; i < len; i++){
antagonist[i] = c[i];
}
antagonist[len+1] = '\0';
}
HarryPotterDVD& HarryPotterDVD::operator= (HarryPotterDVD &d){
delete [] antagonist;
episode = d.episode;
int len3;
for(len3 = 0; d.antagonist[len3] != '\0'; len3++);
antagonist = new char[len3 + 1];
for(int i = 0; i < len3; i++){
antagonist[i] = d.antagonist[i];
}
antagonist[len3+1] = '\0';
DVD::operator=(d);
/*
setID(d.getID());
int len;
for(len = 0; d.getTitle()[len] != '\0'; len++);
char * tit = new char[len+1];
for(int i = 0; i < len; i++){
tit[i] = d.getTitle()[i];
}
tit[len] = '\0';
setTitle(tit);
int len2;
for(len2 = 0; d.getDirector()[len2] != '\0'; len2++);
char* dire = new char[len2+1];
for(int i = 0; i < len2; i++){
dire[i] = d.getDirector()[i];
}
dire[len2] = '\0';
setDirector(dire);
*/
return* this;
}
HarryPotterDVDDriver.cpp
#include<iostream>
using namespace std;
#include"DVD.h"
#include"HarryPotterDVD.h"
int main() {
HarryPotterDVD h1;
HarryPotterDVD h2(1, "Chamber of Secrets", "Chris Columbus", 2, "Tom Riddle");
HarryPotterDVD h3(h2);
h1 = h3;
cout << h2.getEpisode() << endl;
cout << h2.getAntagonist() << endl;
h3.display();
h1.setEpisode(5);
h1.setAntagonist("Prabesh");
h1.display();
}
In the default constructor of HarryPotterDVD, you are assigning a random pointer to member variable antagonist which is not created with new[]
HarryPotterDVD::HarryPotterDVD() {
episode = -1;
char* tmp = "";
antagonist = tmp;
}
In the operator=()function, when the statement h1=h3; is being executed, you are deleting the antagonist using delete[] which is causing the segmentation fault.
delete is null-safe. So, in your default constructors, you can just make the pointers to nullptr and delete of them during assigning won't cause any errors. If you change this way, your issue should go away.
HarryPotterDVD::HarryPotterDVD() {
episode = -1;
antagonist = nullptr;
}

Memory leak without allocating any memory?

I'm working on a coding assignment for a C++ class. When I run my program I seem to be dealing with a memory leakage issue, which is weird since I am NOT explicitly allocating any memory in my code. I ran the program under gdb, and it seems as though the program crashes when running the destructor for a Deck object. I tried stepping through the code, but I when I do so I end up in a host of .h files related to vectors. Then suddenly, it stops. I tried going to a TA for some help, but they seem to be as perplexed as I am on the issue.
# include <stdlib.h>
# include <time.h>
# include <iostream>
# include <vector>
# include <stdio.h>
using namespace std;
//function signatures
float bustProbability (const int);
class Deck
{
public:
//data members
vector <int> cardArray;
vector <int> wasteCards;
//constructor
Deck();
//methods
void shuffleDeck();
void populateDeckWithCards();
void removeCopyCards();
int dealCard();
int remainingCards();
void showCards();
};
void Deck::removeCopyCards() {
for (unsigned int i = 0; i < wasteCards.size(); i++) {
bool removedCopy = false;
for (unsigned int j = 0; j < cardArray.size() && removedCopy == false; j++) {
if (cardArray[j] == wasteCards[i]) {
cardArray.erase (cardArray.begin() + j - 1);
removedCopy = true;
}
}
}
}
int Deck::dealCard() {
if (remainingCards() > 0) {
int tmp = cardArray.back();
wasteCards.push_back(tmp);
cardArray.pop_back();
return tmp;
}
else {
populateDeckWithCards();
removeCopyCards();
shuffleDeck();
//shuffle method
int tmp = cardArray.back();
cardArray.pop_back();
return tmp;
}
}
void Deck::populateDeckWithCards() {
//populate regular cards into array
for (int i = 2; i <= 10; i++) {
for (int j = 0; j < 4; j++) {
cardArray.push_back(i);
}
}
//populate J, Q, K into array
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cardArray.push_back(10);
}
}
//populating array with Aces... treating them as special case '100'
for (int i = 0; i < 4; i++) {
cardArray.push_back(100);
}
return;
}
void Deck::showCards() {
for (unsigned int i = 0; i < cardArray.size(); i++) {
cout << cardArray[i] << endl;
}
}
Deck::Deck() {
wasteCards.clear();
cardArray.clear();
populateDeckWithCards();
shuffleDeck();
}
void Deck::shuffleDeck() {
int n = cardArray.size();
for(int a = n-1; a > 0; a--) {
int min = 0;
int max = a;
int j = min + rand() / (RAND_MAX / (max-min + 1) + 1);
int tmp = cardArray[a];
cardArray[a] = cardArray[j];
cardArray[j] = tmp;
}
return;
}
int Deck::remainingCards() {
return cardArray.size();
}
class Player {
public:
//data members
vector <int> playerHand;
//constructor
Player();
//methods
bool isBust();
int count();
void hit(Deck&);
void stand();
bool muckHand();
void showHand();
};
Player::Player() {
playerHand.clear();
}
void Player::showHand() {
for (unsigned int i = 0; i < playerHand.size(); i++) {
cout << playerHand[i] << endl;
}
return;
}
int Player::count() {
int handCount = 0;
for (unsigned int i = 0; i < playerHand.size(); i++) {
if (playerHand[i] != 100)
handCount += playerHand[i];
else {
if (playerHand[i] == 100) {
if ((handCount) > 11) {
handCount += 1;
}
else
handCount += 10;
}
}
}
return handCount;
}
bool Player::isBust() {
if (count() > 21)
return true;
else
return false;
}
void Player::hit(Deck& d) {
playerHand.push_back(d.dealCard());
}
void Player::stand() {
return;
}
bool Player::muckHand() {
playerHand.clear();
return true;
}
float bustProbability (const int threshHold) {
int threshHoldReached = 0;
Deck myDeck;
Player myPlayer;
Player dealer;
for (int i = 0; i < 10000; i++) {
myPlayer.hit(myDeck);
dealer.hit(myDeck);
myPlayer.hit(myDeck);
dealer.hit(myDeck);
while (myPlayer.count() < threshHold) {
myPlayer.hit(myDeck);
}
if (!(myPlayer.isBust())) {
++threshHoldReached;
}
myDeck.wasteCards.clear();
myPlayer.muckHand();
dealer.muckHand();
}
float bustFraction = float(threshHoldReached)/float(10000);
return bustFraction;
}
int main () {
cout << "blackjack simulation" << endl;
srand((unsigned int)time(NULL));
cout << bustProbability(19);
return 0;
}
I'm incredibly sorry for just posting my code, but I've spend 4 days on this issue, and I can't even begin to figure out what the problem is.
There is at least the line
cardArray.erase (cardArray.begin() + j - 1);
which seems to be dubious in case of j = 0

Adding counter to bubblesort function

I need to calculate the total number of swapping process and sorting running time for my bubble sort function. For running time, I was successful. But for the total number of swapping processes, I couldn't really understand what to do. I thought of initializing "count" and then tried to call it into the main function. That was a failure.
This if my bubble sort function:
void bubbleSort(T patient[], int size)
{
bool noChange = true; // stop when a pass causes no change
for(int i = size; i > 0; i--)
{
noChange = true;
for(int j = 1; j < i; j++)
{
if(patient[j] < patient[j - 1])
{
swap(patient[j], patient[j-1]);
count = count + 1;
noChange = false;
} // end if
} // end for(j)
if (noChange)
return; // sorted--no need to continue
} // end for(i)
}
"count" seems to show no value when called into the main function. Any tips on what I should try so that I could get the total number of swapping process in this?
EDIT 3:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <time.h>
#include <string>
#include <ctime>
using namespace std;
const int SIZE = 5;
template <class T>
void printArray(T ar[], int sz);
template <class T>
int bubbleSort(T ar[], int sz);
//////////////////////////////////////////////////////////////////////////
// Main Function Implementation
//////////////////////////////////////////////////////////////////////////
int main() {
int numOfData = 50000;
string line, temp;
ofstream resultFile;
string patient[numOfData];
ifstream dataFile("shufflePatient.txt");
int times,i,count;
cout << "Program to shuffle data" << endl << endl;
cout << "This program will calculate swapping processes and running time.";
/*Storing data*/
cout << "Reading data in process.." << endl;
if (dataFile.is_open()) {
i=-1;
while (dataFile.good()) {
getline (dataFile, line);
if (i>=0) patient[i] = line;
i++;
}
dataFile.close();
}
double start_s=clock();
bubbleSort(patient,SIZE);
double stop_s=clock();
cout << "time: " << (stop_s-start_s)/double(CLOCKS_PER_SEC) << endl;
count = bubbleSort(patient,SIZE) ;
cout << "swapping process : " << count ;
cin.get(); // hold window open
/*Writing to file*/
cout << "Writing to file.." << endl;
resultFile.open ("test.txt");
for (int i=0 ; i<numOfData ; i++) {
resultFile << patient[i] << "\n";
}
resultFile.close();
system("pause");
return 0;
}
//----------------------------------------------------------------------------
// prints array of size size
//----------------------------------------------------------------------------
template <class T>
void printArray(T patient[], int size)
{
for(int i = 0; i < size; i++)
cout << patient[i] << " ";
cout << endl;
}
//----------------------------------------------------------------------------
// sorts array of size size by Bubble Sort method
//----------------------------------------------------------------------------
template <class T>
int bubbleSort(T patient[], int size) //returning an int
{
int count = 0; //initializing count
bool noChange = true;
for(int i = size; i > 0; i--)
{
noChange = true;
for(int j = 1; j < i; j++)
{
if(patient[j] < patient[j - 1])
{
swap(patient[j], patient[j-1]);
count = count + 1;
noChange = false;
}
}
if (noChange)
return count; // returning count
}
return count; // returning count
}
This is my updated code. Count value returns to 0. I don't know if the code I've used is right or wrong (where i call the return value of count). Any thoughts?
PS
Also, after changing my functions from void to int, for some reason my code stops sorting the data alphabetically when its written into the "text" file. Whats up with this?
You are not using the return value from the function, why don't you make the function return int - and return the count of number of swaps:
int bubbleSort(T patient[], int size) //returning an int
{
int count = 0; //initializing count
bool noChange = true;
for(int i = size; i > 0; i--)
{
noChange = true;
for(int j = 1; j < i; j++)
{
if(patient[j] < patient[j - 1])
{
swap(patient[j], patient[j-1]);
count = count + 1;
noChange = false;
}
}
if (noChange)
return count; // returning count
}
return count; // returning count
}
PS
The problem in the original code could be where you declared or initialized count (which is not shown in the code snap).
Also, using local variable is usually a better practice than using global ones.

C++ HEAP error when delete [] is called

I keep getting the error in VS 2100 "CRT detected that the application wrote to memory before start of heap buffer"
Can anyone help? My int Main is all the way on the bottom. The error occur when the delete [] command is run on the operator= function
#include "intset.h"
const int MAXINITIALSIZE = 5;
int IntSet::numOfArray = 0;
IntSet::IntSet(int a, int b, int c, int d, int e)
{
numOfArray++;
int tempArray[] = {a, b, c, d, e};
size = determineHighest(tempArray) + 1; //determines largest int
cout << "size is " << size << endl;
arrayPtr = new bool[size]; //creates array of bool
for (int i = 0; i < size; i++) //fill bool array
{
arrayPtr[i]= false; //arrayptr is a bool pointer created in the header
}
for (int i = 0; i < MAXINITIALSIZE; i++)
{
arrayPtr[tempArray[i]]= true;
}
for (int i = 0; i < size; i++)
{
cout << &arrayPtr[i] << endl;
}
}
IntSet::IntSet(const IntSet &intsetObject)
{
numOfArray++;
size = intsetObject.size;
arrayPtr = new bool[size];
for (int i = 0; i < size; i++)
{
if (intsetObject.arrayPtr[i])
arrayPtr[i] = intsetObject.arrayPtr[i];
}
}
IntSet::~IntSet()
{
--numOfArray;
delete [] arrayPtr;
arrayPtr = NULL;
}
int IntSet::determineHighest(int tempArray[])
{
int temp = tempArray[0];
for (int i = 1; i < MAXINITIALSIZE; i++)
{
if (tempArray[i] > temp)
temp = tempArray[i];
else
continue;
}
return temp;
}
IntSet& IntSet::operator=(const IntSet &intsetObject) //ask about IntSet&
{
cout << "inside operator=" << endl;
if (&intsetObject != this)
{
for (int i = 0; i < size; i++)
{
cout << &arrayPtr[i] << endl;
}
delete [] arrayPtr; //HEAP ERROR HERE!
for (int i = 0; i < size; i++)
{
cout << &arrayPtr[i] << endl;
}
size = intsetObject.size
arrayPtr = new bool[size]();
for (int i = 0; i < size; i++)
{
if (intsetObject.arrayPtr[i])
arrayPtr[i] = intsetObject.arrayPtr[i];
}
}
return *this;
}
ostream& operator<<(ostream &output, const IntSet &intsetObject)
{
output << "{ ";
for (int i = 0; i < intsetObject.size; i++)
{
if (intsetObject.arrayPtr[i] == true)
{
output << i << " ";
}
else
continue;
}
output << "}";
return output;
}
//main
#include "intset.h"
int main() {
IntSet object2(9);
IntSet object4(3,6);
object4 = object2;
return 0;
}
This can only happen if arrayPtr is accessed with a negative index. I suspect your defaults for a,b,c,d,e are -1 in the declaration for IntSet::IntSet, so it is writing to arrayPtr[-1] in the set-true loop. Check for tempArray[i] >= 0 there.
Also, you can't print the array after you have deleted it, so you should remove those lines after the delete, although they should be "harmless" in that only garbage will be printed, but who knows - the OS could release the page containing the array and it could segfault your program.
Finally, you should not test if (intsetObject.arrayPtr[i]) in the copy & = operators. Otherwise all "false" elements in the source array become uninitialized in the destination array (new bool[size] does not initialize the array to all false).