Click here to Skip to main content
15,894,646 members
Please Sign up or sign in to vote.
1.33/5 (2 votes)
See more:
Hi all,
I have a virtual function that should return an array of ints.
The array length is different in the various implementations of the function.
My question is what is the right way to declare such a function?
My current decleration is
int* MyFunc(int &iNumberOfElements)

where iNumberOfElements is the number of elements in the returned array.
Each function implementation returns a different array.
Is there another "smarter" way to do it? may be pass the function a
pointer to int and copy the array to it in some way (how?)

Thanks
dj4400
Posted
Updated 7-Jun-10 3:53am
v2

Use std::vector - with RVO and NRVO it's as efficient to return a vector as to fart about returning pointers to blocks of memory and a size.

Cheers,

Ash

PS: In case you don't know... The C++ standard says that functions that have the forms:

A do_something_RVO()
{
    ....

    return A( param );
}

or

A do_something_NVRO()
{
    A value;

    ....


    return value;
}


can get rid of the copy construction of whatever the return value is assigned to. These days most compilers support these optimisations, if they don't consider downloading either VC++ 2010 express of gcc 4.x which do.
 
Share this answer
 
If you don't want to use an std::vector then the only other option is to return return both a pointer to the array and the number of elements.
int MyFunc(int** pointerToFill)
{
  *pointerToFill = new int;
  return numElements;
}
HRESULT MyFunc(int** pointerToFill, int& iNumElements)
{
  *pointerToFill = new int;
  iNumElements = numElements;

  return SUCCESS;
}


I don't think there really is a 'smarter' way.
Replacing the regular array with an std::vector shouldn't really cause that many problems though. You can still use it exactly the same as an array but instead of having an extra variable to store the number of elements it will contain the number itself and you don't need to worry so much about allocating and freeing memory. To save a little typing you can also set up a typedef.
typedef std::vector<int> MyIntArra
 
Share this answer
 
v2
Unless there's a specific reason not to use a std::vector, I'd just have the method declaration return that.

std::vector<int> MyFunc()</int>


That way you don't have to return the number of items returned as an out parameter, the std:vector will know how many items it's holding.


Hope this helps,
Fredrik
 
Share this answer
 
There are many ways you can do this depending on the situation.

I quite often use out parameters to avoid copying (since the move constructor isn't available on all compilers, and for other reasons)

One thing I try to tell people is to avoid allocating memory in a function and return it for someone else to clean up. This is the #1 reason for memory leaks. It's hard to see the allocation scope if it crosses functions, translation units and, God forbid, module boundaries. A good rule is to free memory as close to the allocation point as possible. This might result in letting the caller allocate memory instead of the callee. You will need a query mechanism to get the size needed, but this approach can have some real performance benefits when it comes to reusing allocated space. (This applies to GC languages too)

This is of course not always possible, but for most of the other cases you can write a class that takes care of the memory management.

...and then we have your case where you for one reason or another need a specific function signature. Return newly allocated memory pointers if you know you have things under control, but avoid letting them out to the public.

Depending on how the array is used, you can create a class that has an operator (int*) and return such an instance.
You can have function-local memory caching or maybe use a memory pool to increase the level of control and performance.

oops. Time's up.
 
Share this answer
 
Thanks for the quick reply.
Unfortunately the function must return an array and not a vector.
The overall idea of my work is to upgrade an application with minimal changes in the original code (all the changes are implemented via an interface).

dj4400
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900