Exception thrown at 0x0F4D514F (vcruntime140d.dll) in Project70.exe: 0xC0000005: Access violation writing location 0xDDDDDDDD

1

I am trying to change a class member's value that created in heap with address and getting the error down below.

class class2 {
private:
    string String = "x";
public:
    string function() {
        return String;
    }
};

class class1 {
public:
    string String;
    class2* i;
        void  address(class2* x) {
        x = new class2();
        i = x;
    }

        void function(string x) {
            String = x;
    }
};



int main() {
    int len;
    cin>>len;
    class1 **Class1 = new class1*[len];

    for(int i = 0; i < len; i++) {
        Class1[i] = new class1[i];
    }

    Class1[0]->address(Class1[0]->i);
    Class1[0]->function(Class1[0]->i->function());
    cout<<Class1[0]->String;

}

Exception thrown at 0x0F4D514F (vcruntime140d.dll) in Project70.exe: 0xC0000005: Access violation writing location 0xDDDDDDDD.

c++
class
new-operator
undefined-behavior
memory-mapped-files
asked on Stack Overflow Oct 16, 2019 by oldBear • edited Oct 16, 2019 by Vlad from Moscow

2 Answers

3

This call of the new operator

Class1[i] = new class1[i];

is invalid. You mean

Class1[i] = new class1; 

Pay attention to that this member function

void  address(class2* x) {
        x = new class2();
        i = x;
    }

does not make great sense because the passed argument to the function is not used.

answered on Stack Overflow Oct 16, 2019 by Vlad from Moscow
0

Okay, lets take this step by step, to illustrate what's going wrong. It's pretty clear you're learning C++, so I'll try to write to that audience.

    int len;
    cin>>len;

1) read in a length from standard in. No serious problems yet. You could check to be sure it's not negative or zero, but we'll let that slide for now. We'll pretend that "len = 3", and move on from here.

    class1 **Class1 = new class1*[len];

2) you create a pointer to pointer to class1 called Class1. I can't say that I like your naming scheme, but lets work passed that too, and set Class1 to an array of pointers to class1. So far so good. If len were zero or negative, you can imagine the problems you might have. Note that none of the memory for those pointers has been initialized, just set aside to hold things you put in it later.

    for(int i = 0; i < len; i++) {
        Class1[i] = new class1[i];
    }

3) This will create some new instances of class1, and point Class1[I] at them. With len = 3, this will create a weird grid of allocations. The first array will be of length ZERO, the second of length 1, and the third of length 2. ZERO length arrays are bad.

So with that zero length array ready to blow up like a land mine when we step on it, lets go for a walk!

Class1[0]->address(Class1[0]->i);

First of all, this is pretty misleading. It would be better written as Class1[0][0].address(Class1[0][0].i); Second, passing 'i' into a function whose sole purpose is to write to a member variable that happens to be that parameter you just passed in is pointless. Just write to the member variable.

And third: Boom. We just stepped on the zero-length-array-land-mine. But all is not lost.

You can salvage this with a relatively small number of changes.

  • Class1[i] = new Class1[len]; will give you a grid of allocations (3, 3, 3) rather than a triangle (0, 1, 2).
  • for every call to new you need a call to delete, preferably in that class's destructor. Destructors are awesome. You call new in address (remove it's parameter, you don't need it), so somewhere need to call delete. Also, you should set i to nullptr in the constructor so you don't accidentally try to delete something invalid.
  • for every call to new[] you need a call to delete[]. You looped through an array calling new[], so you need to loop through that array calling delete[] to clean it up.
  • Variable names. I'm guessing English isn't your first language, and you're learning C++ too, so I understand. However, your function and variable names are meaningless at best (class1, class2, i, x), and misleading at worst (address doesn't take anything's address, it creates something). Even with not much to go on, you could at least use names like "InnerClass", "OuterClass", "message", "createInner", "innerPtr"... and they wouldn't be nearly as difficult to figure out.

<RANT MODE> What are we, mathematicians?! We have all the space we need to describe things, so be descriptive. Mathematicians used to be confined to a blackboard, and had to write everything by hand, so some pressure to use (overly) concise (impossible for outsiders to comprehend) notations was understandable... but now? They don't eve have that excuse. And I'm looking at you too Physicists! Yeah you, in the lab coat! </RANT MODE>

And learn to touch type. Programmers end up typing a LOT, and looking from screen to keyboard and back kills your typing speed.

answered on Stack Overflow Oct 16, 2019 by Mark Storer

User contributions licensed under CC BY-SA 3.0