0

I have been working on a project for my computer science class and have encountered an issue with the code working. I am shown no error except when I try to compile and I get an error that reads:

Exception thrown: write access violation. _Left was 0xCCCCCCCC.

The purpose of my project is to take a list of names from an external file, read them into an array, sort said array and then output the sorted list all while using a class for the code. Here is a copy of my code and I would like to extend my gratitude to whoever can help me through my issue:

**Header File**

#include <iostream>


using namespace std;


class person
{
public:
    person();
    bool get(ifstream&);
    void put(ofstream&);

private:
    int capacity = 0;
    string first_name[CAPACITY];
    string last_name[CAPACITY];
    int age[CAPACITY];



};```

**Header function definitions cpp file**

#include<iostream>
#include<string>
#include<fstream>
#include<cstdlib>

const int CAPACITY=20;
using namespace std;

#include "Person.h"

//Names constructor
//Postcondition both first name and last name initialized to zero


person::person()
{
    first_name[CAPACITY] = "";
    last_name[CAPACITY] = "";
    age[CAPACITY]=0;

}

bool person::get(ifstream& in)
{
    in >> first_name[CAPACITY] >> last_name[CAPACITY] >> age[CAPACITY];
    return(in.good());

}
void person::put(ofstream &out)
{
    out << first_name[CAPACITY] << last_name[CAPACITY] << age[CAPACITY];
}

**cpp file which holds main**

#include<iostream>
#include<cstdlib>
#include<fstream>
#include<string>

const int CAPACITY = 20;
using namespace std;
#include "Person.h"


void pop(string *xp, string *yp);
void sort(string name[CAPACITY], int count);

int main()
{
    class person names[CAPACITY];
    ifstream infile;
    ofstream outfile;
    string filename;
    string name[CAPACITY];
    int n = 0;

    cout << "Enter the file name you wish to open" << endl;
    cin >> filename;
    infile.open(filename + ".txt");
    outfile.open("Person_New.txt");

    if (infile.fail())
    {
        cout << "The file requested did not open" << endl;
        exit(1);
    }
    while (!infile.eof())
    {
        names[n].get(infile);
        n++;
    }
    sort(name, CAPACITY);
    for (int i = 0; i < CAPACITY; i++)
    {
        names[i].put(outfile);
    }
    cout << "The file has been created" << endl;

    infile.close();





}
void pop(string *xp, string *yp)
{
    string temp = *xp;
    *xp = *yp;
    *yp = temp;
}
void sort(string name[CAPACITY], int count)
{
    int i, j;
    for (i = 0; i < count - 1; i++)
    {

        for (j = 0; j < count - i - 1; j++)
        {
            if (name[j] > name[j + 1])
            {
                pop(&name[j], &name[j + 1]);
            }

        }
    }
} 

Once again Thank you for any support
  • 3
    You don't need *any* array in `person` class. And you are using them incorrectly - `[CAPACITY]` means something different when *declaring* an array and when you are *using* an array. `name` array in `main` is never initialized with anything useful - all you have there are empty strings. Note that it's completely unrelated to your `names` array. Also [Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons) – Yksisarvinen Jan 25 '20 at 22:54
  • I don't think that's how you are supposed to use strings actually – Asteroids With Wings Jan 25 '20 at 22:56
  • I'd suggest ditching the resource you are currently using for learning C++ and getting [a good book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) instead. C++ is not an easy language and using it correctly is even harder. – Yksisarvinen Jan 25 '20 at 23:01
  • 1
    Amongst many other things, statements like ` first_name[CAPACITY] = "";` write past the end of the array. Valid array indices are `0...CAPACITY-1` in your case. – 3Dave Jan 26 '20 at 20:58
  • Don't use arrays, use `std::vector` instead. – Olaf Dietsche Jan 26 '20 at 20:59

1 Answers1

0

It sounds to me like the compiler is getting upset that you are trying to write (i.e. assign a value) at an address that you do not have permission to access. I believe your constructor for the class person might be at fault because of how this class stores its variables, as well as the class header:

Constructor for the class person:

`person::person(){
    first_name[CAPACITY] = "";
    last_name[CAPACITY] = "";
    age[CAPACITY] = 0;
}`

Class header for the class person:

`class person{
    public:
        //stuff
    private:
        int capacity = 0;
        std::string first_name[CAPACITY];
        std::string last_name[CAPACITY];
        int age[CAPACITY];
        //more stuff
}`

C++ is very specific about its naming conventions, so it makes a distinction between capacity and CAPACITY. Because of this, the variable CAPACITY is not defined within the Person.h file.

Also, because CAPACITY is set to a fixed value in your Person.cpp file, whenever you use first_name[CAPACITY], last_name[CAPACITY], or age[CAPACITY] to assign new values, you are only updating the values at the index equal to CAPACITY unless you update the value of CAPACITY itself. In the code you provided, CAPACITY is equal to 20, so your program attempts to update exclusively index 20 with each method call. This will likely cause issues since the person class only attempts to make its arrays on the runtime stack, with a size of 0 each.

Separately, it seems like you want an array of people, but it appears that you are attempting to use a single person object to store the names and ages of multiple people by making these all arrays. Instead, I would recommend making first_name, last_name, and age not arrays, but rather single variables. Then, you can manipulate an array of type person using your CAPACITY variable. You got pretty close, but you can instead declare it as person myPersonArray[CAPACITY] (no need to mention "class" in front of it -- just be sure that you have #include "Person.h" in your main.cpp file). When you want to update a specific person, you can perform an operation like myPersonArray[updateThisIndexNum].update(newFirstName, newLastName, newAge) or some logical equivalent.

As a final note, I almost always highly recommend against using !infile.eof() to control your while loop when reading any file because eof() only indicates whether you have tried to read past the end of an input file. I would highly recommend checking out this post on Stack Overflow where people far more knowledgeable than I explain exactly why this is usually dangerous and how to avoid it.

Shaavin
  • 125
  • 8