What does "Unhandled exception thrown: read access violation. _First was nullptr" error mean?

25,805

Your copy constructor never sets the target's value, so when you try to use the new string, value is uninitialized. Instead of using the local variable newCopy, you should assign to value.

MyString::MyString(const MyString& newWord) {

    //perform a deep copy to copy each of the value to a new memory
    size = newWord.size;
    value = new char[size];

    for (int ii = 0; ii < size; ii++) {
        value[ii] = newWord.value[ii];
    }
}

Also, the constructor that takes char* chars must make a copy of chars. Otherwise, the pointer could become invalid if the parameter was a local array that has gone out of scope, or a dynamic array that was deleted. Also, since the destructor does delete[] value;, it requires that this be dynamically-allocated, which wouldn't be correct when you initialize it from string literals.

//constructor with an argument
MyString::MyString(char* chars) {

    size = strlen(chars);
    value = new char[size];
    for (int i = 0; i < size; i++) {
        value[i] = chars[i];
    }
}
Share:
25,805
Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin over 1 year

    I compiled my code, but it threw me "Exception thrown: read access violation. _First was nullptr."

    I literally have no idea what this means as I'm still a beginner in C++. I really need your help to figure this problem as I've been struggling with this code for days, and it's so frustrating...

    Thank you in advance.

    #include <iostream>
    #include <cstring>
    #include <fstream>
    using namespace std;
    
    class MyString {
    public:
    
        //default constructor
        MyString();
    
        MyString(char* chars);
    
        //copy constructor
        MyString(const MyString &);
    
        int length() const;
    
        //destructor
        ~MyString();
    
        //operator overloads
        char& operator[](int index);
        friend MyString operator+(const MyString& newWord, const MyString& newWord2);
        MyString& operator+=(const MyString& newWord);
        friend ostream& operator<<(ostream& newWord, const MyString& newWord2);
        friend istream& operator >> (istream& newWord, MyString& newWord2);
        friend bool operator==(const MyString& newWord, const MyString& newWord2);
        friend bool operator!=(const MyString& newWord, const MyString& newWord2);
        friend bool operator<(const MyString& newWord, const MyString& newWord2);
        friend bool operator<=(const MyString& newWord, const MyString& newWord2);
        friend bool operator>(const MyString& newWord, const MyString& newWord2);
        friend bool operator>=(const MyString& newWord, const MyString& newWord2);
    
    private:
        char* value;
        int size;
    };
    
    //default constructor
    MyString::MyString() {
    
        value = NULL;
        size = 0;
    }
    
    //copy constructor
    MyString::MyString(const MyString& newWord) {
    
        //perform a deep copy to copy each of the value to a new memory
        size = newWord.size;
        char* newCopy = new char[size];
    
        for (int ii = 0; ii < size; ii++) {
            newCopy[ii] = newWord.value[ii];
        }
    }
    
    //constructor with an argument
    MyString::MyString(char* chars) {
    
        //give the value and the size
        value = chars;
        size = strlen(chars);
    }
    
    //find length
    int MyString::length() const {
    
        return size;
    }
    
    //find the value of each index
    char& MyString::operator[](int index) {
    
        return value[index];
    }
    
    //operator + (concatenate)
    MyString operator+(const MyString& newWord, const MyString& newWord2) {
    
        MyString concatenated;
        concatenated = strcat(newWord.value, newWord.value);
        return concatenated;
    
    }
    
    //operator += (append)
    MyString& MyString::operator+=(const MyString& newWord) {
    
        char * newMemory = value;
        value = new char[strlen(value) + newWord.length() + 1];
        strcpy(value, newMemory);
        strcat(value, newWord.value);
        if (size != 0)
        {
            delete[] newMemory;
        }
        size = strlen(value);
        return *this;
    }
    
    //ostream operator
    ostream& operator<<(ostream& newWord, const MyString& newWord2) {
    
        newWord << newWord2.value;
        return newWord;
    }
    
    
    //istream operator
    istream& operator >> (istream& newWord, MyString& newWord2) {
    
        const int MAX = 100;
        char* ptr = new char[MAX];
        newWord >> ptr;
        newWord2 = MyString(ptr);
        delete ptr;
        return newWord;
    }
    
    //all boolean operators
    bool operator==(const MyString& newWord, const MyString& newWord2) {
        if (newWord.value == newWord2.value) {
            return true;
        }
        else {
            return false;
        }
    }
    
    bool operator!=(const MyString& newWord, const MyString& newWord2) {
        if (newWord.value != newWord2.value) {
            return true;
        }
        else {
            return false;
        }
    }
    
    bool operator<(const MyString& newWord, const MyString& newWord2) {
        if (newWord.value < newWord2.value) {
            return true;
        }
        else {
            return false;
        }
    }
    
    bool operator<=(const MyString& newWord, const MyString& newWord2) {
        if (newWord.value <= newWord2.value) {
            return true;
        }
        else {
            return false;
        }
    }
    
    bool operator>(const MyString& newWord, const MyString& newWord2) {
        if (newWord.value > newWord2.value) {
            return true;
        }
        else {
            return false;
        }
    }
    
    bool operator>=(const MyString& newWord, const MyString& newWord2) {
        if (newWord.value >= newWord2.value) {
            return true;
        }
        else {
            return false;
        }
    }
    
    //destructor to release memory
    MyString::~MyString() {
        delete[] value;
    }
    
    void test_copy_and_destructor(MyString S) {
        cout << "test: copy constructor and destructor calls: " << endl;
        MyString temp = S;
        cout << "temp inside function test_copy_and_destructor: " << temp << endl;
    }
    
    int main() {
    
        MyString st1("abc abc");
        MyString st2("9fgth");
    
        cout << "Copy constructor , << operator" << endl;
    
        MyString  st3(st1);
    
        cout << "st3: " << st3 << endl;
    
        test_copy_and_destructor(st2);
    
        MyString  st4;
    
        cout << "operator + " << endl;
    
        st4 = st3 + st2;
    
        cout << "st4: " << st4 << endl;
    
        cout << "st1 + st2: " << (st1 + st2) << endl;
    
        cout << "operators  [ ] " << endl;
    
        for (int i = 0; i < st2.length(); i++)
            cout << st2[i] << " ";
    
        cout << endl;
    
        cout << "operators  += , ==, != " << endl;
    
        st2 += st1;
    
        if (st3 == st1)
            cout << "st3 and st1 are identical " << endl;
        else cout << "st3 and st1 are not identical " << endl;
    
        if (st2 != st1)
            cout << "st2 and st1 are not identical " << endl;
        else cout << "st2 and st1 are identical " << endl;
    
        cout << "operators  < , <=, >, >= " << endl;
    
        if (st2 < st1)
            cout << "st2 < st1 " << endl;
        else cout << "st2 is not less than st1 " << endl;
    
        if (st1 <= st2)
            cout << "st1 <= st2 " << endl;
        else cout << "st1 is not less than or equal to st2 " << endl;
    
        if (st1 > st2)
            cout << "st1 > st2 " << endl;
        else cout << "not (st1 >  st2) " << endl;
    
        if (st1 >= st2)
            cout << "st1 >= st2 " << endl;
        else cout << "not (st1 >=  st2) " << endl;
    
        cout << "operator >> " << endl;
    
        //Open the data file
        ifstream input("A9_input.txt");
        if (input.fail()) {
            cout << "unable to open input file A9_input.txt, Exiting..... ";
            system("pause");
            return 0;
        }
        MyString temp1;
        MyString temp2("aaa");
        input >> temp1;
        input >> temp2;
        cout << "first element of input file: " << temp1 << endl;
        cout << "second element of input file: " << temp2 << endl;
        input.close();
    
        cout << "MyString says farewell....." << endl;
        system("pause");
        return 0;
    }
    
    • Bo Persson
      Bo Persson over 7 years
      So how far do you get before the error appears?
    • Barmar
      Barmar over 7 years
      You're trying to do something with the string pointed to by value, but value is NULL.
    • kfsone
      kfsone over 7 years
      You've tried to walk before you can run - this code is a mess. No null checks, operator+ has numerous bugs in it - it shouldn't even compile since you use a const MyString as the first argument to strcat, never mind that strcat requires that the destination buffer be large enough to receive the second additional text. In operator+= you use newMemory to store the old address... Your operator>> is weird, your comparison operators compare pointers, and your destructor assumes you own the pointer which is not the case if constructed with MyString(char* s).
  • Admin
    Admin over 7 years
    I still get this error when I tried to implement the code you suggested: Exception thrown at 0x0F5E0E09 (ucrtbased.dll) in ConsoleApplication5.exe: 0xC0000005: Access violation writing location 0x005D2000. Do you have any idea with this one? Sorry, I've just been using C++ for two months. Thanks for your great help!
  • Admin
    Admin over 7 years
    still get this error when I tried to implement the code you suggested: Exception thrown at 0x0F5E0E09 (ucrtbased.dll) in ConsoleApplication5.exe: 0xC0000005: Access violation writing location 0x005D2000. Do you have any idea with this one? Sorry, I've just been using C++ for two months. Thanks for your great help!
  • Barmar
    Barmar over 7 years
    Sorry, you have lots of code there, I can't see all the possible problems you have with it. You need to learn how to use a debugger so you can look at the variables at each step of the program, and see when they become invalid.
  • Aconcagua
    Aconcagua over 7 years
    This is too little information to guess what the actual error might be. Added some code that might be of use for you.