[C++] Significance of **?

Started by
4 comments, last by Zahlman 17 years, 6 months ago
Hi All, This is something I don't understand in Cpp. Take this function prototype (from direct 3d): HRESULT LockAttributeBuffer(DWORD Flags, DWORD ** ppData); What is the significance of the '**'? Wouldn't it create a pointer, then dereference the pointer? How does this work? Thanks in advance.
Advertisement
actually this is termed a double pointer. It's a pointer to a pointer, which can be useful for many things, such as 2D arrays
To be able to change ppData in the LockAttributeBuffer function, you pass a pointer to ppData:
HRESULT LockAttributeBuffer(DWORD Flags, DWORD * ppData);

To be able to change an DWORD* ppData in the LockAttributeBuffer function, you pass in a pointer to a pointer to ppData:
HRESULT LockAttributeBuffer(DWORD Flags, DWORD ** ppData);

This technique is used to implement "out" parameters. For example:

//Always initialize your pointers to null.DWORD* data = NULL;//This function doesn't care about data, it just sets the pointerHRESULT result = LockAttributeBuffer(Flags, &data);//Now data should point to something useful, unless something went wrong.Assert(data != NULL);
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
I mainly program in C# now, so others who freaquent C and C++ can correct me if I overstep my bounds.

I believe the ** means a pointer to a multidimensional array. It could also be written as *ppData[]. I've also seen ** used to reference an array you might be creating inside of a function. I believe my second explaination is probably the answer here because you're dealing with a buffer you've locked and directx will won't to know if you've changed or added to the buffer. Here I'm assuming you're freeing and allocating new space, which is where the extra * comes in.

I hope this helps, and if I'm wrong please correct me.
Awesome, thanks guys. It makes sense when I think about it like that.
Because the line in question is a function declaration, each comma-separated item describes a parameter - so it's a type name, followed optionally by a parameter name. In that context, '*' can't possibly be the dereference operator - or the multiplication operator, for that matter. And parameter names don't have '*'s in them, so both '*'s must belong to the type name.

For all Foo, Foo* is a pointer to Foo.

There's nothing that says Foo can't have a * in it.

So 'DWORD **' is (DWORD*)*. A pointer to a pointer to a DWORD.

As to *why* you pass a pointer to a pointer to a DWORD, and how you should create the pointer - you need to read the documentation for the function. I think deathkrush probably has got it, but there are other reasons for doing this sort of thing, such as Charles Thomas pointed out (pun very much intended) - among even others.

But in well-written C++, it's rare to want to do this sort of thing, and arguably never really necessary. It's just that the Direct3D API has to support C as well.

This topic is closed to new replies.

Advertisement