2011-03-25 4 views
0
typedef struct _lnode{ 
    struct _lnode *next; 
    size_t row; 
    size_t column; 
    short data; 
}lnode; 

typedef struct _matrix{ 

    size_t width; 
    size_t height; 
    size_t k; 

    int **data; 

}matrix; 

matrix* make_matrix(size_t width, size_t height, size_t k){ 

    matrix *m= malloc(sizeof(matrix)); 
    //matrix *m= malloc(sizeof(*matrix)); DOES NOT WORK 
    if(m==NULL) return NULL; 

    m->width = width; 
    m->height = height; 

    /* 
    Since m->data is a int **, it points to int *, 
    so I have to allocate a number of int *-sized objects to store in it. 
    */ 
    m->data = malloc(sizeof(int *)*height); 
    if(m->data == NULL){ 
     free(m); 
     return NULL; 
    } 

    for(size_t i=0; i < height; i++){ 
     m->data[i] = malloc(sizeof(int)*width); 
     if(m->data[i] == NULL){ 
      for(size_t j = 0; j < i; j++) free(m->data[j]); 
      free(m->data); 
      free(m); 
      return 0; 
     } 

     for(size_t j = 0; j < width; j++) 
      m->data[i][j] = 0; 
    } 

    return m; 
} 


lnode* make_node(size_t row, size_t column, short data){ 
    lnode *newNode = malloc(sizeof(*newNode)); 

    if(newNode==NULL) return NULL; 

    newNode->row = row; 
    newNode->column = column; 
    newNode->data = data; 

    return newNode; 
} 

Ces deux fonctions fonctionnent bien. Dans la fonction make_matrix, j'ai essayé ceC, taille malloc de

matrix *m= malloc(sizeof(*matrix)); 

au lieu de

matrix *m= malloc(sizeof(matrix)); 

Ensuite, il ne fonctionne que pour la première itération dans la boucle et tombe dans l'instruction if

if(m->data[i] == NULL){ 
       for(size_t j = 0; j < i; j++) free(m->data[j]); 
       free(m->data); 
       free(m); 
       return 0; 
      } 

Je sais que sizeof (pointeur) retournera une taille du pointeur. Dans la fonction make_node je fais lnode * newNode = malloc (sizeof (* newNode)); et ça a bien fonctionné. J'essaye de faire la même chose dans la fonction make_matrix. Il ne fonctionne pas cette fois ...

+2

Cela fonctionne bien (comme il se doit) avec 'matrix * m = malloc (sizeof (matrix)); Si oui, quelle est la question? – MAK

Répondre

2

newNode est une variable, donc sizeof *newnode renvoie la taille de la chose vers laquelle il veut pointer. L'équivalent en make_matrix() serait sizeof *m, et non sizeof *matrix.

+2

Je suis peut-être simplement fatigué, mais je ne suis même pas sûr de ce que signifie 'sizeof (* matrix)' pour le compilateur. 'matrix' est un' typedef', donc '* matrix' ne devrait pas avoir de sens (la syntaxe correcte serait' (matrix *) '). – geekosaur

0

Vous dites: « Je sais que sizeof (pointeur) retourne une taille du pointeur »

Mais je ne pense pas que vous faites.

que vous devez faire:

matrix *m = malloc(sizeof(matrix)); 

Sinon, vous obtenez 4 octets (ou 8, si votre machine utilise des pointeurs 64 bits).

"Cela fonctionne" avec ce que vous faites n'est pas correct. Le comportement est indéfini. Tu as juste de la chance.

0

Si je comprends bien votre question, vous dites que votre code échoue parce que m->data[i] n'est pas null?

malloc ne initialise pas votre variable, le contenu de ce que vous obtenez est imprévisible. Utilisez calloc pour initialiser à zéro tous les bits, ou encore mieux si vous avez un standard conforme utilisation du compilateur quelque chose comme

*m = (matrix){ 0 }; 

pour initialiser tous les champs à 0.