calling a function through a pointer - access violation reading location

-1

I have a function that returns a Customer object (not pointer) like this:

Customer CustomerList::retrieve(const int index) const{
        if (index<1 || index>size)
                return false;
        else{
                Node *cur = find(index);
                return (cur->data);
        }
}

This function gets a Customer object from a CustomerList(which is a linkedlist).

I'm trying to manipulate the Customer in the list with following function(this function adds an Account to the Customer object.)

list.retrieve(i).addAccount(acc);

However after this function call, Customer object in CustomerList doesn't change. I assume that the reason is I return a copy of a Customer object, not the object itself.

So in order to return the adress of Customer and manipulate it correctly, i make the following changes to my function.

Customer* CustomerList::retrieve(const int index) const{
        if (index<1 || index>size)
                return false;
        else{
                Node *cur = find(index);
                return &(cur->data);
        }
}

And call the manipulating function like that:

list.retrieve(i)->addAccount(acc);

But it gives me a "Access violation reading location 0x00000044." error. What I want to learn is:

  1. Why doesn't it manipulate the Customer object in first place? Is my assumption right?
  2. After I change my functions and function calls, why does it gives me the error I mentioned above?
c++
pointers
access-violation
asked on Stack Overflow May 7, 2013 by Burak Özmen

2 Answers

1

Why doesn't it manipulate the Customer object in first place? Is my assumption right?

As you say, you're returning a copy and manipulating that, leaving the one in the list untouched.

After I change my functions and function calls, why does it gives me the error I mentioned above?

Almost certainly because of this:

return false;

That will return a null pointer if the index is out of bounds. If that's the behaviour you want, then you'll need to check before dereferencing the pointer:

if (Customer * c = list.retrieve(i)) {
    c->addAccount(acc);
} else {
    // handle the error?
}

and, out of politeness, you should return something that looks more like a null pointer such as nullptr, NULL, or 0.

It might be a better idea to throw an exception (perhaps std::range_error); then the caller can assume that the pointer is valid if the function returns. In that case, it might also be better to return a reference rather than a pointer, giving code very much like your original example:

Customer & CustomerList::retrieve(const int index) const{
    if (index<1 || index>size)
            throw std::range_error("Customer index out of range");
    else{
            Node *cur = find(index);
            return (cur->data);
    }
}

list.retrieve(i).addAccount(acc); // Does exactly what you'd expect

I might also consider moving the range checks into the find function, if that seems appropriate.

answered on Stack Overflow May 7, 2013 by Mike Seymour • edited May 7, 2013 by Mike Seymour
0
  1. Why doesn't it manipulate the Customer object in first place?

Yes you are right. by defualt its retuned by value not by reference so original object in List is not geting modified.

  1. After I change my functions and function calls, why does it gives me the error I mentioned above?

I think you need to share the code of addAccount Method. the problem may be inside it. Considering then with original code return by value it was working corectly (without exception).

answered on Stack Overflow May 7, 2013 by rahul maindargi

User contributions licensed under CC BY-SA 3.0