-1

I am have a few problems with an access violation in my overload operator for a struct. I realize I'm doing something wrong, and it is most likely a silly mistake, however I am just not sure where that may be.

I have the following:

struct Circle
{
    Circle() : innerCircle(nullptr) {}
    Circle * const innerCircle;

    Circle& operator =(Circle *inner)
    {
        innerCircle[0] = inner;    // Exception thrown: read access violation. this was nullptr.
        return *this;
    }
}

void somefunction(Circle * c)
{
    Circle *c2 = new Circle();
    c->innerCircle[0] = c2;
}

Thanks for all the help in advance!

aromans
  • 53
  • 9
  • What is `node`? – Arnav Borborah Feb 02 '18 at 13:34
  • @Arnav Borborah, haha! My bad, mislabeled. – aromans Feb 02 '18 at 13:37
  • 1
    You should use a debugger, but it sure look slike `innerCircle` is null so `innerCircle[0]` is UB. – Borgleader Feb 02 '18 at 13:37
  • 1
    @aromans *I am just not sure where that may be.* -- Not sure? So in your own words, describe what this line does: `c->innerCircle[0] = c2;`. – PaulMcKenzie Feb 02 '18 at 13:39
  • @Borgleader, I did just find out that mpNext is null. I thought I was assigning it a value. Not sure why it is still null. That is where my problem is! :) – aromans Feb 02 '18 at 13:40
  • 1
    ...actually you should describe not only that line, but the whole code, because either you misunderstood something or you are trying to implement a very unconventional assignment operator – 463035818_is_not_an_ai Feb 02 '18 at 13:40
  • P.S: That assignment operator is infinitely recursive... – Borgleader Feb 02 '18 at 13:42
  • @Borgleader I dont think so, because the assigment inside the operator is on pointers – 463035818_is_not_an_ai Feb 02 '18 at 13:42
  • @tobi303 `Circle& operator =(Circle *inner)` -> `innerCircle[0] = inner;` on the lhs we have Circle& on the rhs Circle*. ([Coliru](http://coliru.stacked-crooked.com/a/f6d6c4018c885b8c) link) – Borgleader Feb 02 '18 at 13:44
  • To OP: what do you believe `innerCircle[0]` _means_? If you don't know, why did you add the `[0]`? If you do know, what is it? – Useless Feb 02 '18 at 13:46
  • @Borgleader uh right, sorry got confused. – 463035818_is_not_an_ai Feb 02 '18 at 13:48
  • @Useless, I guess this is kind of my understanding. I have the const pointer to a Circle. So, my pointer cannot change address however the Circle value itself inside the address can change. So my attempt is to change the Circle value inside innerCircle to a different circle – aromans Feb 02 '18 at 13:49
  • @aromans The problem with the way youve defined the operator (on top of the null ptr issue) is its infinitely recursive. You call operator= on a circle, which take a Circle* and then attempts to call operator= on its innercircle (which is also a Circle), which will inturn call operator= on *its* innercircle... see where I'm going with this? – Borgleader Feb 02 '18 at 13:52
  • @Borgleader, yeah I see where your going with that. Oops! :P – aromans Feb 02 '18 at 13:54
  • 1
    @aromans That is an abuse of the assignment operator. Don't use pointers as arguments. An assignment operator's job should be just one thing, assign a `Circle` to another existing `Circle`, and that prototype is `Circle& operator=(const Circle&);`. If you want a function to assign a pointer, then use a different name such as `set_inner_circle` or something similar to that. – PaulMcKenzie Feb 02 '18 at 13:56

2 Answers2

2

Your problem seems to be reasoning about pointers, rather than anything specific to operators.

I have the const pointer to a Circle. So, my pointer cannot change address

true - whatever object your const pointer is initialized to point to, it can never change to point at some other object instead.

however the Circle value itself inside the address can change

Yes,if your const pointer points to an object, you can mutate the object in-place

So my attempt is to change the Circle value inside innerCircle

But this assumes innerCircle points to an object. You initialized it to nullptr, which means it does not point to any object. That's what nullptr (or the old NULL) means.

Since your pointer doesn't point at an object, there's nothing there you can legally mutate. Since you declared your pointer const, you also can't ever change it to point at a real object.

After that, as borgleader says, you get the recursive definition of circle problem.

Maybe Circle should just have a (maybe-nullptr) pointer to circle, which it can mutate to point at a Circle if requested? Eg.

struct Circle
{
    Circle() : innerCircle(nullptr) {}
    Circle* innerCircle;

    void insert(Circle *inner)
    {
        innerCircle = inner;
    }

    bool hasInner() const { return (innerCircle != nullptr); }
    Circle* getInner() const) { return innerCircle; }
};
Useless
  • 64,155
  • 6
  • 88
  • 132
1
Object * const obj;        // read right-to-left:  const pointer to Object
Object const * obj;        // read right-to-left:  pointer to const Object
Object const * const obj;  // read right-to-left:  const pointer to const Object

Look here

Const before or const after?

So you have a constant pointer which is initialized to null in the constructor itself. So You cannot change it later. So in line

c->innerCircle[0] = c2;

you are getting and will always get a null.

AdityaG
  • 428
  • 1
  • 3
  • 17