C++: Program not outputting function return value - c++

I can't figure out why the return value form the "deleteEntry" function is not being output in the last part of my program. It jumps from "Now your list has 5 names again!" to asking if you want to do it again without showing the list without the name you asked it to delete. I know it did it correctly when I tried earlier, but I'm not sure if I changed something without paying attention or if I'm doing something that makes the program do things randomly.
Here's the source code:
#include <iostream>
#include <string>
using namespace std;
int search(string* dynamicArray, int size, string entrytoDelete);
string* addEntry(string *dynamicArray, int&size, string newEntry);
string* deleteEntry(string *dynamicArray, int &size, string entrytoDelete);
int main()
{
char answer;
do
{
string* name;
string name2;
int size = 5;
int x;
name = new string[5];
cout << "\nEnter 5 names:\n";
for(x = 0; x < size; x++)
{
getline(cin, name[x]);
}
cout << endl;
cout << "You entered: \n";
for(x = 0; x< size; x++)
{
cout << *(name + x) << endl;
}
cout << "\nEnter another name: \n";
getline(cin, name2);
name = addEntry(name, size, name2);
cout << "\nYour list now has an extra name!\n";
for(x = 0; x < size; x++)
cout << x << ": " << name[x] << endl;
cout<< "\nPick one name to delete: \n";
getline(cin, name2);
name = deleteEntry(name, size, name2);
cout << "\nNow your list has 5 names again!\n";
for(x = 0; x < size; x++)
cout << x << ": " << name[x] << endl;
cout << "\nWould you like to try again? (Y/N)\n";
cin >> answer;
}while(answer == 'y' || answer == 'Y');
cout << "Goodbye.\n";
return 0;
}
string* addEntry(string *dynamicArray, int&size, string newEntry)
{
string *new_Large = new string[size + 1];
for(int x = 0; x < size; x++)
{
new_Large[x] = *(dynamicArray + x);
}
new_Large[size] = newEntry;
size++;
delete [] dynamicArray;
return new_Large;
}
string* deleteEntry(string *dynamicArray, int &size, string entrytoDelete)
{
int toDelete;
toDelete = search(dynamicArray, size, entrytoDelete);
if(toDelete >= 0)
{
string *new_Small = new string[size - 1];
for(int x = 0; x < (size - 1); x++)
{
new_Small[x] = *(dynamicArray + x);
if(dynamicArray[x] != entrytoDelete)
new_Small[x] = dynamicArray[x];
}
size -= size;
return new_Small;
}
else
{
cout << entrytoDelete << " does not exist.\n";
return dynamicArray;
}
}
int search(string* dynamicArray, int size, string entrytoDelete)
{
int toDelete = -1;
for(int x = 0; x < size; x++)
{
if(*(dynamicArray + x) == entrytoDelete)
{
toDelete = x;
}
}
return toDelete;
}
I'd really appreciate any help.

As other mentioned, this code has memory leaks. I can see many flaws in the code. But, to suggest a small change to produce what you want, you may start with the following changes. See the comments in the code:
#include <iostream>
#include <string>
using namespace std;
int search(string* dynamicArray, int size, string entrytoDelete);
string* addEntry(string *dynamicArray, int&size, string newEntry);
string* deleteEntry(string *dynamicArray, int &size, string entrytoDelete);
int main()
{
char answer;
do
{
string* name;
string name2;
int size = 5;
int x;
name = new string[5];
cout << "\nEnter 5 names:\n";
for(x = 0; x < size; x++)
{
getline(cin, name[x]);
}
cout << endl;
cout << "You entered: \n";
for(x = 0; x< size; x++)
{
cout << *(name + x) << endl;
}
cout << "\nEnter another name: \n";
getline(cin, name2);
name = addEntry(name, size, name2);
cout << "\nYour list now has an extra name!\n";
for(x = 0; x < size; x++)
cout << x << ": " << name[x] << endl;
cout<< "\nPick one name to delete: \n";
getline(cin, name2);
name = deleteEntry(name, size, name2);
cout << "\nNow your list has 5 names again!\n";
for(x = 0; x < size; x++)
cout << x << ": " << name[x] << endl;
cout << "\nWould you like to try again? (Y/N)\n";
cin >> answer;
}while(answer == 'y' || answer == 'Y');
cout << "Goodbye.\n";
return 0;
}
string* addEntry(string *dynamicArray, int&size, string newEntry)
{
string *new_Large = new string[size + 1];
for(int x = 0; x < size; x++)
{
new_Large[x] = *(dynamicArray + x);
}
new_Large[size] = newEntry;
size++;
delete [] dynamicArray;
return new_Large;
}
string* deleteEntry(string *dynamicArray, int &size, string entrytoDelete)
{
int toDelete;
toDelete = search(dynamicArray, size, entrytoDelete);
if(toDelete >= 0)
{
string *new_Small = new string[size - 1];
for(int x = 0, y = 0; x < size; x++) //<- start of changes
{ //
// new_Small[x] = *(dynamicArray + x); //<- remove this
if(dynamicArray[x] != entrytoDelete) //
new_Small[y++] = dynamicArray[x]; //<- x to y++
} //
--size; //<- end of changes
return new_Small;
}
else
{
cout << entrytoDelete << " does not exist.\n";
return dynamicArray;
}
}
int search(string* dynamicArray, int size, string entrytoDelete)
{
int toDelete = -1;
for(int x = 0; x < size; x++)
{
if(*(dynamicArray + x) == entrytoDelete)
{
toDelete = x;
}
}
return toDelete;
}

In your deleteEntry:
size -= size;
This will always set size = 0. I think you're looking to do:
size--;

Related

Dictionary with pointers

I want to write a program that adds words to a lexicon with pointers. However, I must not use strdup(), how can I do that? Below is what I tried but it gives me this error:
Exception thrown at 0x7C87EE72 (ucrtbased.dll) in (name of the file.exe): 0xC0000005: Access violation writing location 0xCDCDCDCD.
The problem is in the newStr() function.
#include <cstring>
#include <string>
#pragma warning (disable:4996)
#include <iostream>
using namespace std;
void delStr(char**&, int&, char*);
void newStr(char**&, int&, char*);
void printchar(char**, int, char);
char* searchStr(char**&, int&, char*);
void printAll(char**&, int);
enum ACTIONS { NEW, DELETE, SEARCH, PRINTLETTER, PRINTALL, EXIT };
int main() {
char** lexicon = NULL;//pointer to pointer fo the dictionary
int x = 0;
int size = 0;
char word[81];
char ch;
cout << "Enter 0-5:" << endl;
cin >> x;
while (x < 0 || x > 5) {//while loop for correct input
cout << "ERROR" << endl;
cin >> x;
}
while (x >= 0 && x <= 5) {
switch (x) {
case NEW:
cout << "Enter the word:" << endl;
ch = cin.get();
cin.getline(word, 80);
newStr(lexicon, size, word);
printAll(lexicon, size);
break;
case DELETE:
cout << "Enter the word to delete:" << endl;
ch = cin.get();
cin.getline(word, 80);
delStr(lexicon, size, word);
printAll(lexicon, size);
cout << endl;
break;
case SEARCH:
cout << "Enter the word to search for:" << endl;
ch = cin.get();
cin.getline(word, 80);
searchStr(lexicon, size, word);
break;
case PRINTLETTER:
cout << "Enter the char:" << endl;
ch = cin.get();
ch = cin.get();
printchar(lexicon, size, ch);
cout << endl;
break;
case PRINTALL:
if (size > 0 && lexicon != NULL) {
printAll(lexicon, size);
}
break;
case EXIT:
return 0;
break;
}
cout << "Enter your choice:" << endl;
cin >> x;
while (x < 0 || x > 5) {//while loop for correct input
cout << "ERROR" << endl;
cin >> x;
}
}
return 0;
}
void printAll(char**& lex, int size) {
for (int i = 0; i < size; i++) {
cout << lex[i] << " ";
}
cout << endl;
}
void newStr(char**& lex, int& size, char* word) {
int i = 0;
for (i = 0; i < size; i++) {
if (strcmp(lex[i], word) == 0) {
//cout << "Word " << word << " already exists\n";
return;
}
}
if (size == 0) {
lex = new char* [1];
for (int i = 0; i < strlen(word); i++) {
strcpy(*lex, word);
}
size++;
}
else {
char** temp = new char* [size + 1];
for (i = 0; i < size; i++) {
temp[i] = lex[i];
}
//strcpy(temp[size],word);
strcpy(temp[size], word);
delete[] lex;
lex = temp;
size++;
}
}
void delStr(char**& lex, int& size, char* word) {
int j = 0;
for (int i = 0; i < size; i++) {
if (strcmp(lex[i], word) == 0) {
for (j = i; j < size - 1; j++) {
lex[j] = lex[j + 1];
}
size--;
char** temp = new char* [size];
for (j = 0; j < size; j++) {
temp[j] = lex[j];
}
delete[] lex;
lex = temp;
}
}
}
void printchar(char** lex, int size, char ch) {
for (int i = 0; i < size; i++) {
if (lex[i][0] == ch) {
cout << lex[i] << " ";
}
}
}
char* searchStr(char**& lex, int& size, char* word) {
for (int i = 0; i < size; i++) {
if (strcmp(lex[i], word) == 0) {
cout << "Found" << endl;
//cout << "Word " << word << " already exists\n";
return lex[i];
}
}
cout << "Not found";
return NULL;
}

C++ My files were working before I attempted to move them into a source file, and now there are no errors and nothing being displayed

My apologies for being a little vague about the issue(s) in the topic, but I really am not sure. I am attempting to create a course_directory as a lab project for school, and up until now everything had been progressing quite well. I have written and tested each of the function in the main.cpp before attempting to move the class functions into the .hpp file. My goal is to have nothing in main except for a call to "Run" that will open a file, and in turn make a call to "displayMenu", and allow the user to interact with the information as they choose, but now everything is compiling correctly, and nothing is being displayed.
Course_directory.hpp
#include "Course_Directory.h"
using namespace std;
Course_Directory::Course_Directory(){};
Course_Directory courses[1001];
void Course_Directory::displayMenu(){
cout << "1.Print all courses" << endl;
cout << "2.Print all courses for a department" << endl;
cout << "3.Print roster for a course" << endl;
cout << "4.Print the largest class" << endl;
cout << "5.Swap two classes" << endl;
cout << "6.Print schedule for a student" << endl;
cout << "7.Exit" << endl;
char dept[50], dept2[50];
int courseNo, courseNo2, i, choice;
while (choice != 7) {
cout << "\nEnter your choice: ";
cin >> choice;
if (choice == 1)
printAllCourses(i);
else if (choice == 2) {
cout << "\nEnter department name:";
cin >> dept;
for(int j = 0; j < sizeof(dept); j++)
{
dept[j] = (toupper(dept[j]));
}
coursesInDept(dept, i);
}
else if (choice == 3) {
cout << "\nEnter course number:";
cin >> courseNo;
studentsInCourse(courseNo, i);
}
else if (choice == 4) {
largestClass(i);
}
else if (choice == 5) {
cout << "\nEnter first department name :";
cin >> dept;
for(int j = 0; j < sizeof(dept); j++)
{
dept[j] = (toupper(dept[j]));
}
cout << "\nEnter first course number: ";
cin >> courseNo;
cout << "\nEnter second department name :";
cin >> dept2;
for(int k = 0; k < sizeof(dept2); k++)
{
dept2[k] = (toupper(dept2[k]));
}
cout << "\nEnter second course number: ";
cin >> courseNo2;
swap2(dept, courseNo, dept2, courseNo2, i);
}
else if (choice == 6) {
int id;
cout << "\nEnter a student Id:";
cin >> id;
schedule(id, i);
}
}
cout << "Goodbye!\n";
}
void Course_Directory::printAllCourses(int len){
for (int i = 0; i < len; i++)
cout << "Course name: " << courses[i].courseName << ", Course
number: " << courses[i].courseNum << endl;
cout << len;
}
void Course_Directory::coursesInDept(char *dept, int len) {
for (int i = 0; i < len; i++)
if (strcmp(dept, courses[i].courseName) == 0)
cout << "Course Name: " << courses[i].courseName << ",
Course number: " << courses[i].courseNum << endl;
}
void Course_Directory::studentsInCourse(int courseNo, int len) {
for (int i = 0; i < len; i++)
if (courseNo == courses[i].courseNum) {
for (int m = 0; m < courses[i].numStudents - 1; m++)
cout << courses[i].IDs[m] << ",";
cout << courses[i].IDs[courses[i].numStudents - 1] <<
endl;
}
}
void Course_Directory::largestClass(int len) {
int max = -999;
for (int i = 0; i < len; i++) {
if (courses[i].numStudents > max)
max = courses[i].numStudents;
}
for (int i = 0; i < len; i++) {
if (courses[i].numStudents == max){
cout << "\nThe largest class is in department: " <<
courses[i].courseName
<< ", and the course number is: " << courses[i].courseNum
<< "\n";
cout << "The class currently has " << max << " students
enrolled.\n";
}
}
}
void Course_Directory::swap2(char *firstDep, int firstNo, char
*secondDep, int secondNo, int len) {
Course_Directory temp;
int firstIndex, secondIndex;
for (int i = 0; i < len; i++) {
if (strcmp(firstDep, courses[i].courseName) == 0 &&
courses[i].courseNum == firstNo)
firstIndex = i;
if (strcmp(secondDep, courses[i].courseName) == 0 &&
courses[i].courseNum == secondNo)
secondIndex = i;
}
temp = courses[firstIndex];
courses[firstIndex] = courses[secondIndex];
courses[secondIndex] = temp;
}
void Course_Directory::schedule(int id, int len) {
cout << "Courses student " << id << " is enrolled in: " << endl;
for (int i = 0; i < len; i++) {
for (int j = 0; j < courses[i].numStudents; j++)
if (courses[i].IDs[j] == id)
cout << courses[i].courseNum << " \n";
}
}
Course_Directory.h
#ifndef COURSE_DIRECTORY_H
#define COURSE_DIRECTORY_H
#include <iostream>
using namespace std;
class Course_Directory{
private:
int* deptSize;
string filename;
public:
char courseName[1001];
int courseNum;
int numStudents;
int IDs[1001];
int* choice;
void displayMenu();
Course_Directory();
//Course_Directory(const Course_Directory& original);
//~Course_Directory();
//void run(string);
void coursesInDept(char*, int);
void studentsInCourse(int, int);
void largestClass(int);
void swap2(char*, int, char*, int, int);
void schedule(int, int);
void printAllCourses(int);
};
#include "Course_Directory.hpp"
#endif //COURSE_DIRECTORY_H
main.cpp
#include "Course_Directory.h"
using namespace std;
class Course_Directory;
int main() {
ifstream file;
file.open("input.txt");
char *token;
int i = 0, j;
Course_Directory courses[100];
if (!file.fail()) {
std::string line;
while (getline(file, line)) {
j = 0;
char *str = const_cast<char *>(line.c_str());
token = strtok(str, " ");
while (token != NULL)
{
if (j == 0)
strcpy(courses[i].courseName, token);
else if (j == 1)
courses[i].courseNum = atoi(token);
else if (j == 2)
courses[i].numStudents = atoi(token);
else
courses[i].IDs[j - 3] = atoi(token);
j++;
token = strtok(NULL, " ");
cout << courses[i].courseName << endl;
}
i++;
}
file.close();
}
else{
cout << "File not found." << endl;
}
//menu
Course_Directory displayMenu();
return 0;
}
If I leave Course_Directory off of displayMenu(); then I get "displayMenu" was not declared in this scope. I'm not sure what the problem is or why the menu will not display. Any help would be greatly appreciated!

Organizing names by last name with three of the same surnames (C++)?

I have an assignment to sort a list of names alphabetically by last name. However, there are three names with the same surname and I can't get the first names to alphabetize with the surnames. Have to code own bubble sort or other sorting algorithm. I chose bubblesort because it's one of the only ones we've learned so far. Any help is appreciated. Everything works except the correct assortment.
Here is my code:
// my name
// Program 6
// This program will show a list of names in a variety of orders.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const int size = 25;
void showContacts_FNLN(string fnameArray[], string lnameArray[], int size);
void showContacts_LNFN(string lnameArray[], string fnameArray[], int size);
void reverseContacts_FNLN(string fnameArray[], string lnameArray[], int size);
void reverseContacts_LNFN(string fnameArray[], string lnameArray[], int size);
void searchLasname(string lnameArray[], string fnameArray[], int size);
void searchFirname(string fnameArray[], string lnameArray[], int size);
void bubbleSort(string lnameArray[], string fnameArray[], int size);
int main(int argc, const char * argv[])
{
int count = 0;
int ans;
ifstream nameData;
string lnameArray[size];
string fnameArray[size];
string lname, fname;
nameData.open("names.txt");
while(nameData >> fname >> lname)
{
fnameArray[count] = fname;
lnameArray[count] = lname;
count ++;
}
bubbleSort(lnameArray, fnameArray, size);
while(ans != 9)
{
cout << "What would you like to do?" << endl;
cout << "1) display contacts by first name and last name" << endl;
cout << "2) display contacts by last name and first name" << endl;
cout << "3) display contacts by first name and last name in reverse order" << endl;
cout << "4) display contacts by last name and first name in reverse order" << endl;
cout << "5) search for contact by last name" << endl;
cout << "6) search for contact by first name" << endl;
cout << "9) exit" << endl;
cout << "Enter: ";
cin >> ans;
cout << endl;
switch(ans)
{
case 1: showContacts_FNLN(fnameArray, lnameArray, size); // shows contacts in FN-LN order
break;
case 2: showContacts_LNFN(lnameArray, fnameArray, size); // LN-FN order
break;
case 3: reverseContacts_FNLN(fnameArray, lnameArray, size); // reversed FN-LN order
break;
case 4: reverseContacts_LNFN (fnameArray, lnameArray, size); // reversed LN-FN order
break;
case 5: searchLasname(lnameArray, fnameArray, size); // searches based on LN
break;
case 6: searchFirname(fnameArray, lnameArray, size); // searches based on FN
break;
case 9: cout << "Goodbye!" << endl;
break;
}
}
nameData.close();
return 0;
}
void showContacts_FNLN(string fnameArray[], string lnameArray[], int size)
{
for(int i=0; i<size; i++)
{
cout << fnameArray[i] << " " << lnameArray[i] << endl;
}
cout << endl;
}
void showContacts_LNFN(string lnameArray[], string fnameArray[], int size)
{
for(int i=0; i<size; i++)
{
cout << lnameArray[i] << ", " << fnameArray[i] << endl;
}
cout << endl;
}
void reverseContacts_FNLN(string fnameArray[], string lnameArray[], int size)
{
for(int i=(size-1); i>=0; i--)
{
cout << fnameArray[i] << " " << lnameArray[i] << endl;
}
cout << endl;
}
void reverseContacts_LNFN(string fnameArray[], string lnameArray[], int size)
{
for(int i=(size-1); i>=0; i--)
{
cout << lnameArray[i] << ", " << fnameArray[i] << endl;
}
cout << endl;
}
void searchLasname(string lnameArray[], string fnameArray[], int size)
{
int c = 0;
string slnam;
cout << "Enter a last name: ";
cin >> slnam;
for(int i=0; i<size; i++)
{
if(slnam==lnameArray[i])
{
cout << lnameArray[i] << ", " << fnameArray[i] << endl;
c++;
}
}
if (c == 0)
{
cout << "There is no match.";
cout << endl;
}
cout << endl;
}
void searchFirname(string fnameArray[], string lnameArray[], int size)
{
int c = 0;
string sfnam;
cout << "Enter a first name: ";
cin >> sfnam;
for(int i=0; i<size; i++)
{
if(sfnam==fnameArray[i])
{
cout << fnameArray[i] << " " << lnameArray[i] << endl;
c++;
}
}
if (c==0)
{
cout << "There is no match." << endl;
}
cout << endl;
}
void bubbleSort(string lnameArray[], string fnameArray[], int size)
{
string tmp, tmp2;
//int count=0;
for( int i = 1; i <= size - 1; i++ )
{
for( int j = 0; j < size - i; j++ )
{
//count++;
if( lnameArray[j] > lnameArray[j+1] )
{
tmp = lnameArray[j];
lnameArray[j] = lnameArray[j+1];
lnameArray[j+1] = tmp;
}
if(lnameArray[j] == lnameArray[j+1])
{
if(fnameArray[j] > fnameArray[j+1])
{
tmp = lnameArray[j];
lnameArray[j] = lnameArray[j+1];
lnameArray[j+1] = tmp;
tmp2 = fnameArray[j];
fnameArray[j] = fnameArray[j+1];
fnameArray[j+1] = tmp2;
}
}
}
}
//cout << "count = " << count << endl;
}
Here you go:
void bubbleSort(string lnameArray[], string fnameArray[], int size)
{
for( int i = 0; i < size - 1; i++ )
{
for( int j = 0; j < size - i - 1; j++ )
{
string name1 = lnameArray[j] + fnameArray[j];
string name2 = lnameArray[j + 1] + fnameArray[j + 1];
if(name1.compare(name2) > 0)
{
string tmp = lnameArray[j];
lnameArray[j] = lnameArray[j + 1];
lnameArray[j + 1] = tmp;
tmp = fnameArray[j];
fnameArray[j] = fnameArray[j + 1];
fnameArray[j + 1] = tmp;
}
}
}
}
Instead of having another 'if' for those that have similar last names, I combined the last name and the first name instead then used it for comparison.
I also noticed in your code in for( int j = 0; j < size - i; j++ ) that you forgot to add - 1 after size - i. Once j == size - i - 1 (assuming that i == 0 currently) then you use j + 1 to access an index, this will cause a segmentation fault since you're accessing an index beyond its range.
Your sort doesn't work because you change the position of the last names only (except for the case where two last names are equal.)
You should use a struct to store this information together in one array. Then you can simplify your code a lot:
struct Person {
Person() = default;
Person(string firstname, string lastname) : firstname(std::move(firstname)), lastname(std::move(lastname)) {}
string firstname;
string lastname;
};
void showContacts_FNLN(Person personArray[], int size) {
for (int i = 0; i < size; i++) {
cout << personArray[i].firstname << " " << personArray[i].lastname << endl;
}
cout << endl;
}
void bubbleSort(Person personArray[], int size) {
for (int i = 1; i <= size - 1; i++) {
// The condition must size - i - 1 because otherwise personArray[j+1] is faulty
for (int j = 0; j < size - i - 1; j++) {
if (personArray[j].lastname > personArray[j+1].lastname
|| (personArray[j].lastname == personArray[j+1].lastname &&
personArray[j].firstname > personArray[j+1].firstname)) {
auto tmp = std::move(personArray[j]);
personArray[j] = std::move(personArray[j+1]);
personArray[j+1] = std::move(tmp);
}
}
}
}
int main(int argc, const char * argv[]) {
int count = 0;
ifstream nameData;
Person personArray[size];
string lname, fname;
nameData.open("names.txt");
while(nameData >> fname >> lname) {
personArray[count] = Person(fname, lname);
count++;
}
nameData.close();
bubbleSort(personArray, size);
showContacts_FNLN(personArray, size);
return 0;
}
I removed some non-essential parts from this example to keep it very short but you should get the idea. (Note that my code makes use of C++11 move semantics, if this confuses you, just remove them.)
Some more suggestions:
Do not use using namespace std;. (The internet will tell you why.)
If you can, use std::array, which eliminates the need to always pass the size of the arrays and allows you to use a C++11 range for loop.

Bubble sorting doesn't work to sort dynamic array of objects in C++

I have class City with following private data: name of city(type char), width(double),length(double) and height(double) of the city. I have to make dynamic array, which is inserted by constructor by default- City(),when the programs starts.Then the program uses method output() and prints inserted array of cities.mA is my object of cities.I should use bubble sort to sort the cities by their length.I have copy constructor, operator = and I have to convert double max(this is variable, used in bubble sort to store current max value) to type City and in this purpose I used contructor with one parameter: City(double max).The problem is that the sort doesn't work. I think that the problem is in my definition of constructor with one parameter(to convert type double to type city).
#include "stdafx.h"
#include<iostream>
#include<math.h>
#include <algorithm>
using namespace std;
class City{
private: char *name;
double width;
double length;
double height;
public:
void Output();
City();
~City();
City(double max){
name = "";
width = 0;
length = max;
height = 0;
}
double GetLength()
{
return length;
}
double GetWidth(){ return width; }
double GetHeight(){ return height; }
char GetName(){ return *name; }
City(const City& that)
{
name = new char[strlen(that.name) + 1];
for (int i = 0; i <= strlen(that.name); i++)
name[i] = that.name[i];
//strcpy(name, that.name);
width = that.width;
length = that.length;
height = that.height;
}
City& operator=(const City that)
{
name = that.name;
width = that.width;
length = that.length;
height = that.height;
return*this;
}
};
City::City()
{
char ime[20];
cout << "Name= ";
cin >> ime;
name = new char[strlen(ime) + 1];
for (int i = 0; i <= strlen(ime); i++)
name[i] = ime[i];
cout << "Width= ";
cin >> width;
cout << "Length= ";
cin >> length;
cout << "Height= ";
cin >> height;
}
void City::Output()
{
cout << "Name is: " << name << endl;
cout << " Width is: " << width << " deg" << endl;;
cout << " Length is: " << length << " deg" << endl;
cout << " Height is: " << height << " m" << endl;
return;
}
City::~City()
{
cout << " " << endl;
cout << "Destructor of City!" << endl;
delete[] name;
}
int main()
{
int n;
City *mA;
cout << "Input number of cities: " << endl;
cin >> n;
mA = new City[n];
for (int j = 0; j < n; j++)
{
mA[j].Output();
}
cout << "Cities from west to east, sorted by their length" << endl;
double max = mA[0].GetLength();
for (int j = 1; j<n; j++)
{
if (mA[j - 1].GetLength()>mA[j].GetLength())
{
max = mA[j - 1].GetLength();
mA[j - 1] = mA[j];
mA[j] = max;
}
}
for (int j = 0; j < n; j++)
{
mA[j].Output();
}
delete[]mA;
return 0;
}
City::City()
{
char ime[20];
cout << "Name= ";
cin >> ime;
name = new char[strlen(ime) + 1];
for (int i = 0; i <= strlen(ime); i++)
name[i] = ime[i];
...
}
First you have to fix the constructor. Although it is not necessarily wrong, you should not ask for input in the constructor. Add a separate function for Input() instead
City& operator=(const City that)
{
name = that.name;
...
return*this;
}
This assignment operator is wrong. name is a pointer, you don't want to assign the pointers (not in this scenario). You should be using the same method as before to copy the name instead:
name = new char[strlen(ime) + 1];
strcpy(name, ime);
bubble sort should be done like the method in below. Also, you have added #included <string>. You should be using std::string instead!
#include <iostream>
#include <string>
using namespace std;
class City
{
private:
char *name;
double width;
double length;
double height;
public:
City()
{
name = nullptr;
width = 0;
length = 0;
height = 0;
}
City(const City& that)
{
name = new char[strlen(that.name) + 1];
strcpy(name, that.name);
width = that.width;
length = that.length;
height = that.height;
}
City& operator=(const City that)
{
name = new char[strlen(that.name) + 1];
strcpy(name, that.name);
width = that.width;
length = that.length;
height = that.height;
return*this;
}
~City()
{
delete[] name;
}
void Input()
{
char buffer[100];
cout << "Name= ";
cin >> buffer;
name = new char[strlen(buffer) + 1];
strcpy(name, buffer);
cout << "Width= ";
cin >> width;
cout << "Length= ";
cin >> length;
cout << "Height= ";
cin >> height;
}
void Output()
{
cout << "Name is: " << name << ", " << length << endl;
cout << " Width is: " << width << " deg" << endl;
cout << " Length is: " << length << " deg" << endl;
cout << " Height is: " << height << " m" << endl << endl;
}
double GetLength() { return length; }
double GetWidth() { return width; }
double GetHeight() { return height; }
char GetName() { return *name; }
};
int main()
{
int n;
City *mA;
cout << "Input number of cities: " << endl;
cin >> n;
City *mA = new City[n];
//read input
for(int j = 0; j < n; j++)
mA[j].Input();
//bubble sort:
for(int i = 0; i < n; i++)
{
for(int j = i + 1; j < n; j++)
{
if(mA[i].GetLength() > mA[j].GetLength())
{
//swap values:
City temp = mA[i];
mA[i] = mA[j];
mA[j] = temp;
}
}
}
for(int j = 0; j < n; j++)
mA[j].Output();
delete[]mA;
system("pause");
return 0;
}
manually sorting requires comparing of resorted entries
------- comment ---------
for (int j = 1; jmA[j].GetLength()) {
... exchange elements
... j-=2; //index of
... if(j < 0) j=0; }
------- end comment ---------
if there will be used std::sort conditions are reliable checked by STL.
And there will only be checked compare conditions on callback function.
regards, Hubert Hermanutz

Heap Corruption Detected (Simulating Dynamic Array with Static Array)

I wanna simulate dynamic array by using static array. However, when I delete some elements from the array and then try to add the array, I got an error saying 'Heap Corruption Detected'.
Here's my code:
#include <iostream>
#include <algorithm>
using namespace std;
int INIT_SIZE = 5;
int MAX_SIZE = INIT_SIZE;
void printArray(int *arr, int n){
cout << "n= " << n << " >> [";
for(int i = 0; i < n ;i++){
cout << arr[i];
if ( i < n-1)
cout << ",";
}
cout << "]\b\n";
}
bool deleteEl(int *&arr, int &n, int el){
int *newArr;
bool found = false;
int cnt = 0;
if( n == 0){
return false;
}
else{
for(int i = 0; i < n;i++){
if( arr[i] == el){
found = true;
cnt++;
}
}
if( !found){
return false;
}
newArr = new int[n-cnt];
int k = 0;
for(int i = 0; i < n ; i++){
if( arr[i] != el){
newArr[k++] = arr[i];
}
}
n -= cnt;
if (n <= (MAX_SIZE / 2) && (MAX_SIZE / 2) >= INIT_SIZE){
MAX_SIZE /= 2;
}
delete[] arr;
arr = newArr;
}
return true;
}
bool addEl(int *&arr, int &n, int el){
int *newArr;
if( n >= MAX_SIZE){
newArr = new int[2 * MAX_SIZE];
//std::copy(arr,arr+MAX_SIZE, newArr);
for(int i = 0 ; i < n;i++){
newArr[i] = arr[i];
}
n++;
newArr[n-1] = el;
MAX_SIZE *= 2;
delete[] arr;
arr = newArr;
}else{
arr[n++] = el;
}
return true;
}
int main(int argc, char *argv[]){
int *arr = new int[MAX_SIZE];
int n = 0;
int input = 0;
do{
cout << "1. Add Element : " << endl;
cout << "2. Del Element : " << endl;
cout << "3. Exit : " << endl;
cin >> input;
if( input == 1){
cout << "Enter new element : " << endl;
int newEl;
cin >> newEl;
if( addEl(arr, n, newEl)){
cout << "New Element Added. " << endl;
}else{
cout << "Add new element failed. " << endl;
}
}else if (input == 2){
cout << "Enter deleted element : " << endl;
int del;
cin >> del;
if( deleteEl(arr, n, del)){
cout << "Deletion OK" << endl;
}else{
cout << "Deletion Fail. Data Not found." << endl;
}
}else if(input == 3){
cout << "Program exiting ..." << endl;
}else{
cout << "Input is wrong. Enter correct input (1,2, or 3)." << endl;
}
printArray(arr,n);
}while(input != 3);
delete [] arr;
return 0;
}
Have a look at the Hinnant's stack allocator and consider using STL instead of naked arrays.