By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,855 Members | 865 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,855 IT Pros & Developers. It's quick & easy.

Wrong way to pass pointer by value in functions

P: n/a
Hi,

I am still struggling to master C++ and is trying to understand how to
achieve passing arguments using pointers. I got some questions that I
like to post to the experts here, hope you can help to clarify my
doubts. I'm using g++ version 3.3.4. I created 3 classes as below for
testing some concepts. The questions are written as comments in
Bclass.h file. Thank you for your time and tips!

------------runtime errors------------
{8=> main
Aclass created.
Bclass instantiated.
main: Aclass.h:19: void Aclass::test(): Assertion `b' failed.
Aborted
-------------file: main.cc------------
#include "Aclass.h"

int main(){
Aclass a;
a.test();
}

-------------file: Aclass.h-----------
#ifndef ACLASS_H
#define ACLASS_H

#include "Bclass.h"
#include <stack>
#include <cassert>

class Aclass{
public:
Aclass(){
std::cout << "Aclass created." << std::endl;
}
~Aclass(){ std::cout << "Aclass destructed." << std::endl; }

void test(){
Bclass *b=NULL;
if( box.empty() ){
create(b);
assert(b); // As expected this fails during runtime
/* Qn: Is the failure because pointer 'b' is pointing to NULL?
* Qn: Is the reason why the call to "create" function without effect
* because the local pointer 'ptr' was changed to point to a temporary
object?
*/
}
delete b;
}

protected:
void create(Bclass *ptr){
box.push( new Bclass() );
ptr = box.top();
box.pop();// memory is pop
assert(ptr); // this is fine
/* Qn: Is the reason the assertion pass because local pointer 'b' is
* still referencing the memory?
* Qn: Is the memory release or considered unreferenced only if
* we get out of the "create" function?
*/
}

private:
std::stack<Bclass* > box;
};

#endif

-------------file: Bclass.h-----------
#ifndef BCLASS_H
#define BCLASS_H
#include <iostream>

class Bclass{
public:
Bclass(){ std::cout << "Bclass instantiated." << std::endl; }
~Bclass(){ std::cout << "Bclass destroyed." << std::endl; }
};
#endif

Jul 23 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a

"DamonChong" <so********@excite.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
Hi,

I am still struggling to master C++ and is trying to understand how to
achieve passing arguments using pointers. I got some questions that I
like to post to the experts here, hope you can help to clarify my
doubts. I'm using g++ version 3.3.4. I created 3 classes as below for
testing some concepts. The questions are written as comments in
Bclass.h file. Thank you for your time and tips!

------------runtime errors------------
{8=> main
Aclass created.
Bclass instantiated.
main: Aclass.h:19: void Aclass::test(): Assertion `b' failed.
Aborted
-------------file: main.cc------------
#include "Aclass.h"

int main(){
Aclass a;
a.test();
}

-------------file: Aclass.h-----------
#ifndef ACLASS_H
#define ACLASS_H

#include "Bclass.h"
#include <stack>
#include <cassert>

class Aclass{
public:
Aclass(){
std::cout << "Aclass created." << std::endl;
}
~Aclass(){ std::cout << "Aclass destructed." << std::endl; }

void test(){
Bclass *b=NULL;
if( box.empty() ){
create(b);
assert(b); // As expected this fails during runtime
/* Qn: Is the failure because pointer 'b' is pointing to NULL?
Yes.
* Qn: Is the reason why the call to "create" function without effect
* because the local pointer 'ptr' was changed to point to a temporary
object?
Yes.
*/
}
delete b;
}

protected:
void create(Bclass *ptr){
box.push( new Bclass() );
ptr = box.top();
box.pop();// memory is pop
assert(ptr); // this is fine
/* Qn: Is the reason the assertion pass because local pointer 'b' is
* still referencing the memory?
It passes because ptr is pointing to valid memory. There is no b here.
* Qn: Is the memory release or considered unreferenced only if
* we get out of the "create" function?


It's a memory leak, because you created it with new, but never delete it.

If you want to modify something, you need to pass it by reference or via a
pointer. This includes modifying pointers themselves. So you need to pass
the pointer by reference (or via a pointer-to-pointer). Try:

void create(Bclass* &ptr) {...

-Howard


Jul 23 '05 #2

P: n/a

"Howard" <al*****@hotmail.com> wrote in message
news:xg********************@bgtnsc05-news.ops.worldnet.att.net...
* Qn: Is the reason why the call to "create" function without effect
* because the local pointer 'ptr' was changed to point to a temporary
object?


Yes.


Actually, that wasn't a correct response on my part. The pointer ptr is a
local copy (of the pointer b) in the create function. That copy was
assigned a value. But b itself was left unchanged, so it remained NULL.

-Howard

Jul 23 '05 #3

P: n/a

DamonChong wrote:
Hi,

I am still struggling to master C++ and is trying to understand how to achieve passing arguments using pointers. I got some questions that I
like to post to the experts here, hope you can help to clarify my
doubts. I'm using g++ version 3.3.4. I created 3 classes as below for
testing some concepts. The questions are written as comments in
Bclass.h file. Thank you for your time and tips!

------------runtime errors------------
{8=> main
Aclass created.
Bclass instantiated.
main: Aclass.h:19: void Aclass::test(): Assertion `b' failed.
Aborted
-------------file: main.cc------------
#include "Aclass.h"

int main(){
Aclass a;
a.test();
}

-------------file: Aclass.h-----------
#ifndef ACLASS_H
#define ACLASS_H

#include "Bclass.h"
#include <stack>
#include <cassert>

class Aclass{
public:
Aclass(){
std::cout << "Aclass created." << std::endl;
}
~Aclass(){ std::cout << "Aclass destructed." << std::endl; }

void test(){
Bclass *b=NULL;
if( box.empty() ){
create(b);
assert(b); // As expected this fails during runtime
/* Qn: Is the failure because pointer 'b' is pointing to NULL?
* Qn: Is the reason why the call to "create" function without effect
* because the local pointer 'ptr' was changed to point to a temporary object?
*/
}
delete b;
}

protected:
void create(Bclass *ptr){
box.push( new Bclass() );
ptr = box.top();
box.pop();// memory is pop
assert(ptr); // this is fine
/* Qn: Is the reason the assertion pass because local pointer 'b' is
* still referencing the memory?
* Qn: Is the memory release or considered unreferenced only if
* we get out of the "create" function?
*/
}

private:
std::stack<Bclass* > box;
};

#endif

-------------file: Bclass.h-----------
#ifndef BCLASS_H
#define BCLASS_H
#include <iostream>

class Bclass{
public:
Bclass(){ std::cout << "Bclass instantiated." << std::endl; }
~Bclass(){ std::cout << "Bclass destroyed." << std::endl; }
};
#endif

That problem is that yuo're passing the pointer by value.
If you want to modify the calling functions argument, you have to
either pass the pointer by reference, or pass a pointer to a pointer.
Example:
//Ref
void create(Bclass *& ptr){
box.push( new Bclass() );
ptr = box.top();
box.pop();// memory is pop
assert(ptr); // this is fine

Or *********************
//Pointer to a pointer method
void create(Bclass ** ptr){
box.push( new Bclass() );
(*ptr) = box.top();
box.pop();// memory is pop
assert((*ptr)); // this is fine

Another option, which is the one I recommend, is to return the pointer.
Bclass *create(void){
Bclass * ptr = NULL;
box.push( new Bclass() );
ptr = box.top();
box.pop();// memory is pop
assert(ptr); // this is fine
return ptr;

Jul 23 '05 #4

P: n/a
PKH

"DamonChong" <so********@excite.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
Hi,

I am still struggling to master C++ and is trying to understand how to
achieve passing arguments using pointers. I got some questions that I
like to post to the experts here, hope you can help to clarify my
doubts. I'm using g++ version 3.3.4. I created 3 classes as below for
testing some concepts. The questions are written as comments in
Bclass.h file. Thank you for your time and tips!

------------runtime errors------------
{8=> main
Aclass created.
Bclass instantiated.
main: Aclass.h:19: void Aclass::test(): Assertion `b' failed.
Aborted
-------------file: main.cc------------
#include "Aclass.h"

int main(){
Aclass a;
a.test();
}

-------------file: Aclass.h-----------
#ifndef ACLASS_H
#define ACLASS_H

#include "Bclass.h"
#include <stack>
#include <cassert>

class Aclass{
public:
Aclass(){
std::cout << "Aclass created." << std::endl;
}
~Aclass(){ std::cout << "Aclass destructed." << std::endl; }

void test(){
Bclass *b=NULL;
if( box.empty() ){
create(b);
assert(b); // As expected this fails during runtime
/* Qn: Is the failure because pointer 'b' is pointing to NULL?
* Qn: Is the reason why the call to "create" function without effect
* because the local pointer 'ptr' was changed to point to a temporary
object?
*/
}
delete b;
}

Is should fail because b is NULL. When you call create(b), you're just
passing the address (NULL in this case) of whatever b is pointing at as a
parameter, and not b itself. It might help to think of regular variables are
just 'names' for memory-locations where the variables value are stored.
Pointers to variables are the same, only that they use their
memory-locations to store the address of another variables memory-location.

If you want b to point to the object created in 'create', you could return
the address of the new object like this:

Bclass* create(){ return new Bclass();}

or use a pointer to a Bclass pointer like this:

void create(Bclass** pptr){Bclass* ptr = new Bclass(); *pptr = ptr;} //
stores the address of the new object in b's memory location when called like
this 'create(&b);'


protected:
void create(Bclass *ptr){
box.push( new Bclass() );
ptr = box.top();
box.pop();// memory is pop
assert(ptr); // this is fine
/* Qn: Is the reason the assertion pass because local pointer 'b' is
* still referencing the memory?
* Qn: Is the memory release or considered unreferenced only if
* we get out of the "create" function?
*/
}


b has no meaning inside this function. All you know is that you got a
parameter called ptr which contains the memory address of a Bclass object.
The assertion passes because ptr is pointing at the new object. Memory
allocated with 'new' is not released automatically when you leave a
function.

PKH


Jul 23 '05 #5

P: n/a
Thanks alot! That clarifies much!

Jul 23 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.