return a float array in a function

Started by
17 comments, last by cozzie 10 years, 9 months ago

Hi,

I'm trying to make a const function returning a float[3] array with the position of my camera.

But I can't manage to do this, without passing the array as a function parameter.

To be exact, this is what I do now:


void CD3dcam::GetPositionF(float pPos[]) const
{
	pPos[0] = mPosition.x;
	pPos[1] = mPosition.y;
	pPos[2] = mPosition.z;
}

But this is ofcourse annoying if I want to pass GetPositionF to a function as a parameter, where a float array is expected.

So I tried something like

float* CD3dcam::GetPositionF() const

{

float pos[3];

pos[0] = mPosition.x;

pos[1] = mPosition.y;

pos[2] = mPosition.z;

return pos;

}

This compiles, but gives a warning that I'm returning the address of a local variable in memory, instead of a pointer to the actual values.

Any ideas anyone?

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Advertisement

Update;

This seems to work, not sure though if it's correct:


float* CD3dcam::GetPositionF() const
{
	float *pos = new float[3];

	pos[0] = mPosition.x;
	pos[1] = mPosition.y;
	pos[2] = mPosition.z;

	return pos;
}

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

You either get the user to pass you the array (what you had), return the address of a global object or return an object that wraps the array. The last one is probably what I would go for. You seem to be using float[3] to represent points. Make a class Point instead, and return that.

EDIT: Yes, you could also return a dynamically allocated buffer, which is what you did in your second post. But then the calling code needs to remember to delete[] it, and they don't, and this is how you create memory leaks.

You can return a struct (by value, i.e. not via a pointer to the struct) which has a float[3] as its only member as well if you really want to return the array. This may copy but the compiler should be able to optimise the copy out.

Don't return the address of a global variable, it doesn't scale well (meaning: doesn't scale at all) if you need to call it recursively or on multiple threads.

EDIT: I see Alvaro suggested making a Point class, missed that, it's the same as what I suggested using a class instead of a struct.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Thanks.

I'm not sure though if making a struct will bring me what I'm looking for.

The function I have to pass the float array too, expects a pointer array:

HRESULT SetFloatArray(
[in] D3DXHANDLE hParameter,
[in] const FLOAT *pf,
[in] UINT Count
);

That would mean that I have to create a local object of the struct in every frame, filling it with GetPositionF and passing the member of the object to the function above.

Sounds a bit 'waste', although I don't know how to do it easier.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

Make mPosition a union? Of a float[3] array and float x, y, z; Then just pass &mPosition directly.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

I 'solved' it now by making a public member float array: mPosF[3] and update it when the camera moves.

And in the SetFloatArray I just call that public member of my camera class.

This works for now, still not sure if there's a better way though.

Paradigm shifter: that's sort of what I did now, I think :)

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

You could make a conversion operator:


struct Vec3
{
    float x,y,z;
 
    operator float* ()
    {
        return &x;
    }
 
    operator const float* () const
    {
        return &x;
    }

};

I 'solved' it now by making a public member float array: mPosF[3] and update it when the camera moves.

And in the SetFloatArray I just call that public member of my camera class.

This works for now, still not sure if there's a better way though.

Paradigm shifter: that's sort of what I did now, I think smile.png

This is NOT the way to go. If you have public access to the position, you will be able to change it's data without letting your CD3dcam class know about it, which is bad because you'll not be able to cache the view matrix (to recalculate it only when needed later, when you're optimizing).

The best approach is to use a struct much like belfegor posted and have the following methods on your CD3dcam:


const Vec3& getPosition() const
{
   return mPos;
}

void setPosition( const Vec3& pos )
{
   mPos = pos;
}

Update;

This seems to work, not sure though if it's correct:


float* CD3dcam::GetPositionF() const
{
	float *pos = new float[3];

	pos[0] = mPosition.x;
	pos[1] = mPosition.y;
	pos[2] = mPosition.z;

	return pos;
}

Indeed that will work. It'll make it very easy to have memory leaks though, and will possibly bring problems if this method uses a different memory allocator implementation than what is used by the caller to free it up later.

This topic is closed to new replies.

Advertisement