Solved

Returning a class pointer from a function

Posted on 2011-02-13
13
416 Views
Last Modified: 2012-05-11
Hello all,

I want to return a pointer to a class from a function.  The instance of the class is created within the function that is to return the instance. So for example:

MyUDO *MyOtherClass::ReturnUdoMethod()
{
      MyUDO *newUdo = new MyUdo();
      . . .
      return newUdo;
}

There are many obvious problems I have run into so far including default copy constructor issues, scope problems, memory leaks and dangling pointer leaks to name a few.

So without getting into pedantic detail, I would like to know how can I make this happen?

Thanks very much.
0
Comment
Question by:edc
  • 4
  • 3
  • 2
  • +3
13 Comments
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 34885436
"I want to return a pointer to a class from a function"

You can't return a pointer to a class. You can return only a pointer to a tangible object of the class. An object is instantiated in memory. A class is just the logical template which is used to create an object.

return newUdo;  //this is where the pointer created on the heap is being returned

Only thing is you need to be careful to release this memory pointed to by this pointer when the memory is no longer used.
0
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 34885442
but you need to remember that you are doing this inside the member function of another class. Ensure that you include the correct header file.....
0
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 34885452
so you could do this

Class2* Someclass::afn( )
{
  Class2* p = new Class2;

  return p;
}

remember to release the memory pointed to by p. And always check for NULL before using the pointer.
0
 
LVL 1

Author Comment

by:edc
ID: 34885497
>> "I want to return a pointer to a class from a function"

>> You can't return a pointer to a class. You can return only a pointer to a tangible object of the class. >> An object is instantiated in memory. A class is just the logical template which is used to create an >> object.

Thank you for you answer, however I did ask for those who would answer to refrain from pedanticism.  I am aware of a class being a template and not a concrete instance.  The distinction has little to do with the question being asked.

>> Class2* Someclass::afn( )
>> {
>>   Class2* p = new Class2;
>>
>>  return p;
>> }

>> remember to release the memory pointed to by p. And always check for NULL before using the
>> pointer.

So when p goes out of scope how is the instance of the class affected?  Does it continue to exist in memory since it has not been deleted, and as such the memory address that is being passed back remains valid?  Or is there something else going on under the covers?

Thanks.
0
 
LVL 32

Expert Comment

by:phoffric
ID: 34885555
>> Class2* Someclass::afn( )
>> {
>>   Class2* p = new Class2;
>>
>>  return p;
>> }

>> So when p goes out of scope how is the instance of the class affected?
The instance is not affected. It remains in the heap.

>> as such the memory address that is being passed back remains valid?
If you have ptr = afn(); then ptr is now pointing to the valid instance.

If later you wish to delete this instance, you can delete ptr; followed by ptr = NULL;
But if you did  ptr2 = ptr; delete ptr; ptr = NULL;, now you have ptr2 still holding the address of the instance which is now invalid. So, if you dereference ptr2, you may start seeing bugging things happening.
0
 
LVL 12

Expert Comment

by:trinitrotoluene
ID: 34885653
however I did ask for those who would answer to refrain from pedanticism

Then you shouldn't be on EE. And besides your query is of a fundamental truth which seeks a pedagogic reply.


So when p goes out of scope how is the instance of the class affected?  Does it continue to exist in memory since it has not been deleted, and as such the memory address that is being passed back remains valid?  Or is there something else going on under the covers

The memory is valid since it has been created on the heap and not on the stack. If it were created on the stack then the pointer would be pointing to memory which has been released. This is the basic difference between memory allocated on a heap and that on a stack. So not releasing this could result in a memory leak.
This is a fundamental concept not limited only to C++


So

Class2* Someclass::afn( )
{
  Class2* p = new Class2;

  return p;
}

outside afn() the pointer variable 'p' goes out of scope meaning to say you can't use the same pointer variable 'p' in another function. Ofcourse you can always create another variable named 'p' having a different scope

However the memory pointed to by 'p' is still not invalidated and has not been released. So when I returned the pointer from the function it is nothing but the address of this valid area of memory.
Use this address wherever you want.

So

Class1::Somefn()
{
Class2* ptrcopy = afn();
...

...

..
}

If you understand this , you understand memory leaks and what causes them.

As for using default copy constructors, dangling pointers these are once again fundamental issues.

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 11

Expert Comment

by:DeepuAbrahamK
ID: 34885895
Could try something like this
class MyClassFactory
{
    public:
	static int obj_counter;
	MyClass* getInstance( );
};

 MyClass* MyClassFactory::getInstance()

 {
	obj_counter++;
	return new MyClass();
 }

Open in new window

0
 
LVL 32

Assisted Solution

by:sarabande
sarabande earned 200 total points
ID: 34886220
i think returning a pointer newly created in a function which is not member function of the class itself is bad design. there might be exceptions like with smart pointers or with factory classes but in my opinion the 'new' operation should be on same design level as the 'delete' operation what would be not the case for the sample code you posted and what probably is the cause for the problems you have with the approach.

Sara  
0
 
LVL 40

Accepted Solution

by:
evilrix earned 300 total points
ID: 34887006
The design you describe is that of a Factory design pattern and it is a pretty standard thing to do.
http://en.wikipedia.org/wiki/Factory_method_pattern

>> I have run into so far including default copy constructor issues, scope problems, memory leaks and dangling pointer leaks to name a few.

Not sure why you have issues with copy-constructors since you are passing around a pointer to an object rather than the object itself. The issues with memory leaks and dangling pointers can easily be resolved by using smart pointers rather than returning raw pointers that need to be managed and cleaned up. The following article goes into more detail about smart pointers and even provides a simple referenced counted implementation you could use. It also introduces the Boost shared_ptr, which is a tool every C++ programmer should have in their toolkit.

"C++ Smart pointers"
http://e-e.com/A_1959.html
0
 
LVL 32

Expert Comment

by:sarabande
ID: 34887051
in factory pattern the new operation was made by a static or virtual member function of the class which needs to get factured. so you can derive a new class and can provide functionality for factory pattern with that class not needing any second class to add code.

Sara



0
 
LVL 1

Author Comment

by:edc
ID: 34889678
@trinitrotoluene
>>>> however I did ask for those who would answer to refrain from pedanticism

>> Then you shouldn't be on EE. And besides your query is of a fundamental truth which seeks a
>> pedagogic reply.

No it really doesn't.  Your comment regarding instance versus template does not go to the heart of the question which is returning a pointer.  Pedanticism is just irritating and egotistic.

@evilrix

>>>> I have run into so far including default copy constructor issues, scope problems, memory leaks
>>>>  and dangling pointer leaks to name a few.

>> Not sure why you have issues with copy-constructors since you are passing around a pointer to
>> an object rather than the object itself. The issues with memory leaks and dangling pointers can
>> easily be resolved by using smart pointers rather than returning raw pointers that need to be
>> managed and cleaned up. The following article goes into more detail about smart pointers and even
>> provides a simple referenced counted implementation you could use. It also introduces the Boost
>> shared_ptr, which is a tool every C++ programmer should have in their toolkit.

True.  Badly worded.  I should have said that I got into the forest and lost the trees on that remark.  I got so into issues that might arise as I was writing the function that I lost sight of the bigger picture.

@sarabande

>> i think returning a pointer newly created in a function which is not member function of the class
>>  itself is bad design. there might be exceptions like with smart pointers or with factory classes but
>> in my opinion the 'new' operation should be on same design level as the 'delete' operation what
>> would be not the case for the sample code you posted and what probably is the cause for the
> problems you have with the approach.

Very true.  Again I had blinders on a single approach.  Thank you for your thoughts.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 34890465
edc,

It's easy to get side-tracked when struggling with a frustrating problem. I know, I am the worse :)

I hope things are now clearer for you but please do post back here if you need any further assistance on this.

All the best.

-Rx.
0
 
LVL 1

Author Comment

by:edc
ID: 34891084
Hi evilrix. Thanks very much.  I appreciate the note. The EE community is always good at bringing me back to the central point and pointing out better ways to approach the problem, and I will certianly post again when I get myself bound up in thoery :o).
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now