tags:

views:

194

answers:

6

Hi,

I have got a structure and in it a pointer to a 2D array. But when I try to assign an actual 2D array to that pointer I do not succeed - compiler says that my pointer is a pointer to a 1D array.

Here's my code:

typedef GLfloat Vertex2f[2];
typedef GLfloat TextureCoordinate[2];

typedef struct { 
    GLuint texture_name;  // OpenGL ID of texture used for this sprite 
    Vertex2f *vertices; // array of vertices 
    TextureCoordinate *texture_coords; // texture vertices to match

    GLubyte *vertex_indices;
} game_sprite;

void loadState()
{
    game_sprite ballSprite;

    createAndLoadTexture("ball.png", &ballSprite.texture_name);

    const Vertex2f tempVerticesArray[4] =  {
        {-100.0f, -100.0f},
        {-100.0f, 100.0f},
        {100.0f, 100.0f},
        {100.0f, -100.0f}
    };

    ballSprite.vertices = &tempVerticesArray; //The problem appears to be here
}

How can I make it work?

Thanks.

+3  A: 

My C is a little rusty, but shouldn't that be:

ballSprite.vertices = tempVerticesArray;
Mitch Wheat
Richard Pennington
Adam Rosenfield
No, they are not compatible pointer types. One is a pointer to a Vertex2f, the other is a pointer to an array of Vertex2f's.
Richard Pennington
No. I'm an idiot. You are correct.
Richard Pennington
The types of the expressions are *not* compatible; remember that Vertext2F is a typedef for `GLFloat [2]`, so the expression `ballSprite.vertices` is of type `GLFloat (*)[2]` and the type of the expression ` the expression `tempVerticesArray` has type `GLFloat [4][2]`, which will be implicitly converted to `GLFloat (*)[2]`. **EDIT** The `const` issue doesn't help.
John Bode
+3  A: 

in C an array is in fact a pointer to the first member, so when you do

ballSprite.vertices = &tempVerticesArray;

you are actually trying to assign to ballSprite.vertices the value of a pointer to a pointer

drop the & and you'll be fine with ballSprite.vertices = tempVerticesArray;

Alon
In C++, an array is not a pointer, but decays to one in certain contexts.
Georg Fritzsche
@gf: That's true in C as well.
jamesdlin
@jamesdlin: ah, wasn't entirely sure.
Georg Fritzsche
+2  A: 

Just to clarify, I don't think

Vertex2f *vertices 

declares a "2D array", it is a 1-dimensionnal array of Vertex2f.

But as pointed by Mitch, the issue is probably that tempVerticesArray, as declared here, is a 1d-array, which is the same as a pointer to a Vertex2f. So &tempVerticesArray is the address of this pointer (a Vertex2f * * ).

phtrivier
+1  A: 

You could use either

ballSprite.vertices = tempVerticesArray;

or

ballSprite.vertices = &tempVerticesArray[0];
rmn
+7  A: 

You have two problems. First is that tempVerticesArray is const. You can't assign a pointer to a const value (&tempVerticesArray) to a pointer to a non-const variable (ballSprite.vertices) without a typecast, so the compiler is complaining. You should modify the vertices data member to be of the type const Vertex2f *, assuming you're not actually modifying that data ever.

The second problem is that as soon as loadState() ends, the variable tempVerticesArray goes out of scope, and so any dangling pointers to it (specifically ballSprite.vertices) are invalid. You should make tempVerticesArray a static variable so it's not a stack variable that can go out of scope. This is assuming that the ballSprite object is used after that function ends, which I'm guessing it does based on context.

If you do need to modify your vertices after initialization, you'll need to allocate for each ballSprite its own set of vertex data (e.g. using malloc()) and copy the vertex data in (e.g. using memcpy()). If you don't, all ballSprite instances will share a pointer to the same vertex data, and when you modify it, they will all be affected.

Adam Rosenfield
+1 for clarity........
Prasoon Saurav
+1  A: 

You might want to allocate memory for the pointer to hold the data. Then memcpy the temporary array to the newly allocated memory. If you're just trying to make the pointer reference the array directly, you might have an issue when you leave that function. The temporary array made on the stack will be freed before you can use the pointer elsewhere.

GrkEngineer