Problema puntatore ad array di strutture

di il
5 risposte

Problema puntatore ad array di strutture

Ciao a tutti,
io ho la necessità di creare in memoria un array tridimensionale di array di strutture, ed inizializzarlo con determinati parametri.
L'array in questione rappresenta una scacchiera tridimensionale, ovvero un cubo costituito da NxNxN cubi di K vertici ognuno.

Questo è il mio codice:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
	float x;
	float y;
	float z;
} Vertex3D;

#define cubeVertexCount 276
#define CELLS_PER_SIDE 8

Vertex3D cubeVertexData[cubeVertexCount];
Vertex3D (*model)[CELLS_PER_SIDE][CELLS_PER_SIDE][CELLS_PER_SIDE][cubeVertexCount];

int main(int argc, char **argv)
{
	int modelVertexCount = cubeVertexCount * CELLS_PER_SIDE * CELLS_PER_SIDE * CELLS_PER_SIDE;
	int modelSize = modelVertexCount * sizeof(Vertex3D);
	model = malloc(modelSize);
	int modelEndAddress = model + modelSize;
	
	int x = 0, y = 0, z = 0, i = 0;
	for (x = 0; x < CELLS_PER_SIDE; x++) {
		for (y = 0; y < CELLS_PER_SIDE; y++) {
			for (z = 0; z < CELLS_PER_SIDE; z++) {
				Vertex3D (*cellModel)[cubeVertexCount] = &((*model)[x][y][z]);
				memcpy(cellModel, cubeVertexData, cubeVertexCount * sizeof(Vertex3D));
				printf("Cell[%d][%d][%d]'s address: %d\n", x, y, z, cellModel);
				for (i = 0; i < cubeVertexCount; i++) {
					(*cellModel[i]).x += x * 2;
					(*cellModel[i]).y += y * 2;
					(*cellModel[i]).z += z * 2;
					printf("\tVertex[%d]: x=%d, y=%d, z=%d\n", i, (*cellModel[i]).x, (*cellModel[i]).y, (*cellModel[i]).z);
				}
			}
		}
	}
	return 0;
}
Nel mio progetto vero l'array cubeVertexData è dichiarato e inizializzato staticamente in un file .h (contiene un modello 3D creato ed esportato in formato opportuno da Blender), per questo motivo lo copio ad ogni iterazione del ciclo for (z...), per poi andare a modificare con un offset i campi x,y,z della struttura Vertex3D.

Il problema è che ottengo sempre un Segmentation Fault, nonostante l'ide non mi dia alcun warning...
dove sbaglio?

Grazie in anticipo!

5 Risposte

  • Re: Problema puntatore ad array di strutture

    
    Vertex3D (*model)[CELLS_PER_SIDE][CELLS_PER_SIDE][CELLS_PER_SIDE][cubeVertexCount];
    
    è un array di puntatori che puntano a nulla. Non c'è nessun allocazione di memoria e stai scrivendo a vuoto. Probabilmente il problema sta lì.

    Come non detto. Ho visto adesso il malloc. In quale riga ti si presenta l'errore?
  • Re: Problema puntatore ad array di strutture

    skynet ha scritto:


    
    Vertex3D (*model)[CELLS_PER_SIDE][CELLS_PER_SIDE][CELLS_PER_SIDE][cubeVertexCount];
    
    è un array di puntatori che puntano a nulla. Non c'è nessun allocazione di memoria e stai scrivendo a vuoto. Probabilmente il problema sta lì.
    Dichiarato in questo modo, stando a quanto suggerito da più utenti in questa pagina, è un puntatore ad array di array di array di array, non un array di puntatori, quindi dovrebbe essere corretto, anche perchè il segmentation fault capita sempre intorno al vertice [3][5][6][274]. (avrei dovuto specificarlo prima, scusa)

    EDIT: ah ecco, ho letto solo adesso il tuo edit
    L'errore è sempre a questa riga:
    (*cellModel[i]).x += x * 2;
  • Re: Problema puntatore ad array di strutture

    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct {
       float x;
       float y;
       float z;
    } Vertex3D;
    
    #define cubeVertexCount 276
    #define CELLS_PER_SIDE 8
    
    Vertex3D cubeVertexData[cubeVertexCount];
    Vertex3D (*model)[CELLS_PER_SIDE][CELLS_PER_SIDE][CELLS_PER_SIDE][cubeVertexCount];
    
    int main(int argc, char **argv)
    {
       int modelVertexCount = cubeVertexCount * CELLS_PER_SIDE * CELLS_PER_SIDE * CELLS_PER_SIDE;
       int modelSize = modelVertexCount * sizeof(Vertex3D);
       model = (Vertex3D (*)[CELLS_PER_SIDE][CELLS_PER_SIDE][CELLS_PER_SIDE][cubeVertexCount])malloc((sizeof(int)) * modelSize);
       int modelEndAddress = int(model) + modelSize;
       
       int x = 0, y = 0, z = 0, i = 0;
       for (x = 0; x < CELLS_PER_SIDE; x++) {
          for (y = 0; y < CELLS_PER_SIDE; y++) {
             for (z = 0; z < CELLS_PER_SIDE; z++) {
                Vertex3D (*cellModel)[cubeVertexCount] = &((*model)[x][y][z]);
                memcpy(cellModel, cubeVertexData, cubeVertexCount * sizeof(Vertex3D));
                printf("Cell[%d][%d][%d]'s address: %d\n", x, y, z, cellModel);
                for (i = 0; i < cubeVertexCount; i++) {
                   (*cellModel[i]).x += x * 2;
                   (*cellModel[i]).y += y * 2;
                   (*cellModel[i]).z += z * 2;
                   printf("\tVertex[%d]: x=%d, y=%d, z=%d\n", i, (*cellModel[i]).x, (*cellModel[i]).y, (*cellModel[i]).z);
                }
             }
          }
       }
       return 0;
    }
    
    Corretto. Controlla malloc.
  • Re: Problema puntatore ad array di strutture

    skynet ha scritto:



    Corretto. Controlla malloc.
    Grazie!!
    Ma tu risolvi sempre così in fretta i problemi alla gente? O_O
    Perchè se è così preparati perchè approfitterò delle tue conoscenze molto più spesso!

    Solo per curiosità:
    
    int modelSize = modelVertexCount * sizeof(Vertex3D);
    model = (Vertex3D (*)[CELLS_PER_SIDE][CELLS_PER_SIDE][CELLS_PER_SIDE][cubeVertexCount])malloc((sizeof(int)) * modelSize);
    
    come mai è necessario moltiplicare sizeof(int) * modelSize nel malloc?
    per come ho inizializzato modelSize non dovrebbe rappresentare già la dimensione in byte del modello?

    Grazie ancora!
  • Re: Problema puntatore ad array di strutture

    ModelSize è un int. Quindi se vuoi allocare spazio = modelSize dovresti moltplicarlo x il size di int che nella mia versione di VS è 4 byte in un altra non so. Vedi gli utilizzi di malloc c'è sempre sizeof(oggetto). Il tuo oggetto è andato un po perso perche hai convertito tutto in int e alla fine devi fare sizeof(int) * l'oggetto.
Devi accedere o registrarti per scrivere nel forum
5 risposte