Problem with pointers

M

mlt

In a class App I pass a pointer to a function :

class App {
private:
Bob b;
Pop * p;

public:
void do() {
b.init(p)

// Use p for various stuff

}

};


class Bob {
typedef Pop P;


public:
void init(P * p) {
p = new P();

}

};

But after calling b.init(p) in App I get memory errors when I use p. What am
I doing wrong?
 
J

jason.cipriani

In a class App I pass a pointer to a function :

class App {
private:
    Bob b;
    Pop * p;
public:
void do() {
    b.init(p)

   // Use p for various stuff

}
};

class Bob {
    typedef Pop P;

public:
void init(P * p) {
 p = new P();

}
};

But after calling b.init(p) in App I get memory errors when I use p. What am
I doing wrong?


You pass the pointer 'p' to Bob::init() by value, not by reference.
Modifying it's value in Bob::init() only has an effect on the local
function parameter 'p', and does not modify the variable that you've
passed in. Consider a simpler example:

int x = 0;

void set_value_to_5 (int value) {
value = 5;
}

int main () {
set_value_to_5(x);
}

In this example, x is not set to 5. The modification of 'value' in
set_value_to_5() has no effect on x. Passing the parameter by
reference would result in 'x' being modified:

void set_value_to_5 (int &value) { // <-- by reference
value = 5;
}

The same goes for your pointer:

int *x = NULL;

void init_pointer (int *ptr) {
ptr = new int;
}

int main () {
init_pointer(x); // does not modify x
}

You'd want to pass the pointer by reference:

void init_pointer (int * &ptr) {
ptr = new int;
}


You may be getting confused because your syntax resembles a common
technique of using pointers to pass objects by reference, e.g.:

void set_value_to_5 (int *value) {
*value = 5;
}

However, this is not the same as what you are trying to do. The
pointer itself is passed by value. If you did this:


int x = 0;

void set_value_to_5 (int *value) {
*value = 5;
value = new int;
}

int main () {
int *ptr_to_x = &x;
set_value_to_5(ptr_to_x);
}


Then x would be set to 5, although ptr_to_x would still point to x
(and not to a new int).


HTH,
Jason
 
M

mlt

Paavo Helde said:
Here, p is a local variable, the caller does not see changes to its
value. What you need is either to return the new value so it can be
assigned to the p in the caller:

P* init() {
return new P();
}

or maybe pass the parameter by reference if return by value is not
suitable for some reason:

void init(P*& p) {
p = new P();
}


I thought that pointers were always passed as reference and never by value.
 
J

jason.cipriani

I thought that pointers were always passed as reference and never by value.


No, in C++ everything is passed by value, unless you explicitly pass
it by reference. See my reply elsethread, in particular the part at
the end:
You may be getting confused because your syntax resembles a
common technique of using pointers to pass objects by
reference, e.g.:

void set_value_to_5 (int *value) {
*value = 5;
}

The pointer itself is still passed by value (see the remainder of the
example in that post). That is the "C-style" way of passing an int by
reference and is equivalent to this:

void set_value_to_5 (int &value) {
value = 5;
}

And so, while pointers can be used to pass non-pointers "by
reference", pointers themselves are not passed by reference (unless
you explicitly pass them as such).

Jason
 
J

jason.cipriani

It might be conceivable to pass larger objects themselves by reference
automatically (IIRC Java does exactly this)


Off topic, but to be pedantic, all non-POD types in Java are passed by
reference, regardless of size. There is no operator overloading,
however, and assignment always assigns the reference, not the value,
so the semantics are generally equivalent to passing objects by
pointer in C++:

// C++
void function (MyObject *obj) {
obj->whatever(); // modifies the caller's object.
obj = new MyObject; // not seen by caller.
}

// Java
void function (MyObject obj) {
obj.whatever(); // modifies the caller's object.
obj = new MyObject(); // not seen by caller.
}


POD types are all passed by value.


Jason
 
J

James Kanze

Off topic, but to be pedantic, all non-POD types in Java are
passed by reference, regardless of size.

To be really pedantic: Java doesn't allow objects as parameters,
and there is, in fact, no way you can declare a function to take
an object. Java does allow pointers (called reference types in
Java) as parameters, and these are passed by value. So Java's
rules aren't actually very much different than those of C++,
except that a lot of cases aren't allowed.
There is no operator overloading, however, and assignment
always assigns the reference, not the value, so the semantics
are generally equivalent to passing objects by pointer in C++:
// C++
void function (MyObject *obj) {
obj->whatever(); // modifies the caller's object.
obj = new MyObject; // not seen by caller.
}
// Java
void function (MyObject obj) {
obj.whatever(); // modifies the caller's object.
obj = new MyObject(); // not seen by caller.
}
POD types are all passed by value.

Non-reference types are all passed by value. Java doesn't have
the concept of POD. (But non-reference types are quite similar
in most ways.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
KetoBurn
Top