2010-01-01 2 views
0

J'ai une structure et un pointeur vers un tableau 2D. Mais quand j'essaye d'assigner un tableau 2D réel à ce pointeur je ne réussis pas - le compilateur dit que mon pointeur est un pointeur vers un tableau 1D.Modification d'un pointeur sur un tableau en C

Voici mon 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 
} 

Comment puis-je le faire fonctionner?

Merci.

Répondre

7

Vous avez deux problèmes. La première est que tempVerticesArray est const. Vous ne pouvez pas affecter un pointeur à une valeur const (&tempVerticesArray) à un pointeur vers une variable non const (ballSprite.vertices) sans un transtypage, de sorte que le compilateur se plaint. Vous devez modifier le membre de données vertices pour qu'il soit du type const Vertex2f *, en supposant que vous ne modifiez pas réellement ces données.

Le deuxième problème est que dès que loadState() se termine, la variable tempVerticesArray est hors de portée, et donc tous les pointeurs pendants (en particulier ballSprite.vertices) ne sont pas valides. Vous devriez faire tempVerticesArray une variable static afin que ce ne soit pas une variable de pile qui puisse sortir de la portée. Cela suppose que l'objet ballSprite est utilisé après la fin de cette fonction, ce que je suppose en fonction du contexte.

Si vous avez besoin de modifier vos sommets après l'initialisation, vous devrez allouer pour chaque ballSprite son propre ensemble de données de sommet (par exemple à l'aide malloc()) et copier les données de sommet dans (par exemple en utilisant memcpy()). Si ce n'est pas le cas, toutes les instances ballSprite partageront un pointeur vers les mêmes données de sommet, et lorsque vous les modifierez, elles seront toutes affectées.

+0

+1 pour plus de clarté ........ –

3

Mon C est un peu rouillé, mais ne devrait pas être que:

ballSprite.vertices = tempVerticesArray; 
+0

En C/C++ tempVerticesArray a le type "Vertex2f *" et & tempVerticesArray a le type "Vertex2f [2] *". Le premier est un pointeur vers le (premier) élément, le second est un pointeur vers un tableau. –

+0

Non. 'BallSprite.vertices = tempVerticesArray' et' ballSprite.vertices = & tempVerticesArray' sont tous les deux équivalents. 'tempVerticesArray' a le type' const Vertex2f [2] ', et il se désintègre en un pointeur vers un premier élément (de type' const Vertex2f * '). '& tempVerticesArray' a le type' const Vertex2f (*) [2] ', qui est un type compatible avec' const Vertex2f * '. Le problème est avec 'const' correctness. –

+0

Non, ils ne sont pas des types de pointeurs compatibles. L'un est un pointeur sur un Vertex2f, l'autre est un pointeur vers un tableau de Vertex2f. –

3

en C un tableau est en fait un pointeur sur le premier élément, donc quand vous

ballSprite.vertices = &tempVerticesArray; 

vous en train d'essayer d'attribuer à ballSprite.vertices la valeur d'un pointeur vers un pointeur

tomber le & et vous serez très bien avec ballSprite.vertices = tempVerticesArray;

+0

En C++, un tableau n'est pas un pointeur, mais se désintègre en un dans certains contextes. –

+0

@gf: C'est vrai en C aussi. – jamesdlin

+0

@jamesdlin: ah, n'était pas entièrement sûr. –

2

Juste pour clarifier les choses, je ne pense pas

Vertex2f *vertices 

déclare un « tableau 2D », il est un tableau 1 de Vertex2f dimensionnel. Mais comme l'a souligné Mitch, le problème est probablement que tempVerticesArray, comme indiqué ici, est un tableau 1d, qui est le même qu'un pointeur sur un Vertex2f. Donc & tempVerticesArray est l'adresse de ce pointeur (un Vertex2f * *).

1

Vous pouvez utiliser soit

ballSprite.vertices = tempVerticesArray; 

ou

ballSprite.vertices = &tempVerticesArray[0]; 
1

Vous pouvez affecter de la mémoire au pointeur pour contenir les données. Puis mémcpy le tableau temporaire à la mémoire nouvellement allouée. Si vous essayez simplement de faire en sorte que le pointeur référence directement le tableau, vous pouvez rencontrer un problème lorsque vous quittez cette fonction. Le tableau temporaire créé sur la pile sera libéré avant que vous puissiez utiliser le pointeur ailleurs.

Questions connexes