2

I have native C++ class SrcClass containing the following:

std::vector<shotEntry> objectsQueue;

bool getRelatedEntry(const entryToProcess *entriesDeets, int &i) const {
    if (i >= (int)objectsQueue.size()) {
        i = 0;
        return false;}
    if (!objectsQueue.size()) return false;
    entriesDeets = &(objectsQueue[i++]);
    return true;
}

In my client I have:

const entryToProcess *entriesDeets = NULL;
int i = 0;
while (srcObj->getRelatedEntry(entriesDeets, i)) {

When I step through getRelatedEntry the formal parameter, entriesDeets is updated as expected before returning. When it returns the actual parameter of the client is not updated.

This is in some big project I have returned to after two months away. I'm pretty sure the last refactoring I did was to introduce these damnable vectors. It takes ages to compile when I mess with headers. Am I getting confused with the initialize once/ readonly/ const'ness of C#? Can I get away with the client getting a read only native object back?

John
  • 6,433
  • 7
  • 47
  • 82
  • You might be interested in other ways to return multiple values from a function: http://stackoverflow.com/q/321068/10077 – Fred Larson Oct 25 '11 at 14:09
  • Be careful when using pointers to objects inside a vector. If items are added to the vector, reallocation may happen, everything will move, and your pointers will be invalid. – Benjamin Lindley Oct 25 '11 at 14:14
  • My code is entirely synchronous apart from any threads the UI employs. I am literally just grabbing the pointer, updating it to screen and then discarding it. – John Oct 25 '11 at 14:22

3 Answers3

3

entriesDeets is a local variable inside getRelatedEntry. You only modified the local, you didn't affect the value passed in. You need to pass a reference to pointer or a pointer to pointer.

Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
3

This is because you are setting the value of the function's parameter. You want:

bool getRelatedEntry(const entryToProcess **entriesDeets, int &i) const {
    ...
    *entriesDeets = &(objectsQueue[i++]);
    ...

and

srcObj->getRelatedEntry(&entriesDeets, i)
bames53
  • 86,085
  • 15
  • 179
  • 244
  • Or as Benamin Lindley said, a reference to a pointer: `bool getRelatedEntry(const entryToProcess *&entriesDeets, int &i) const {` and no other changes are needed. – bames53 Oct 25 '11 at 14:08
  • But `**` is more readable than `*&` where you might have to understand associativity. – John Oct 25 '11 at 14:13
2

The pointer is updated, but it is the internal copy inside the function. If you want that change to be visible outside of the function, you should pass a reference:

//                                         v
bool getRelatedEntry(const entryToProcess *&entriesDeets, int &i) const {

Or in C style a double pointer and dereference it internally on every usage:

//                                         v
bool getRelatedEntry(const entryToProcess **entriesDeets, int &i) const {
   // ...
   *entriesDeets = &(objectsQueue[i++]);
David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489