2009-07-26 8 views
3

Je suis en train d'exécuter le code suivant (en gcc 4.3 sur fedora 11 i586):pointeur sur struct dans les struct imbriquées

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

struct s_smallstruct{ 
    int smallstruct; 
};      

struct s_test2{ 
     char * test2; 
     struct s_smallstruct* smallstruct; 
}; 

struct s_test3{ 
     char * test3; 
     struct s_smallstruct * smallstruct; 
}; 

struct s_test1{ 
     char * test1; 
     struct s_test2 * test2; 
     struct s_test3 * test3; 
}; 


int main(){ 
     struct s_test1 *test1 = (struct s_test1 *) malloc(sizeof test1); 
     test1->test2[0].smallstruct[0].smallstruct = 123; 
     int num = test1->test2[0].smallstruct[0].smallstruct; 
//  struct s_smallstruct * smallstruct = (struct s_smallstruct *) malloc(sizeof smallstruct); 
//  smallstruct[0].smallstruct =12; 
//  int num = smallstruct[0].smallstruct; 
     printf("%d\n" , num); 
     return EXIT_SUCCESS; 
} 

Mais je me suis un segfault à test1-> test2 [0]. smallstruct [0] .smallstruct = 123; . La partie commentée est en cours d'exécution sans erreur. Quelle est la raison de ce comportement. Je ne suis pas très compétent en C, donc j'apprécierais toute sorte d'aide.

+0

Ce n'est pas une solution, mais il faut vérifier TOUJOURS * ALLOC !! –

Répondre

7

Il y a trois problèmes avec votre code que je peux voir:

  1. sizeof seulement vous indique la taille du pointeur, ce qui est 4 pour les pointeurs 32 bits, pas la taille de la structure est pointée,
  2. et même si vous changez sizeof pour vous dire la taille de la structure, malloc ne fera que allouer de la mémoire pour la structure s_test1, pas pour les structures qui sont pointés du sein,
  3. et enfin, les pointeurs dans test1, test2 etc. doivent être initialisés.

Voici quelque chose qui fonctionne:

const int length = 2;  
struct s_test1 *test1 = malloc(length * sizeof *test1); 
test1->test2 = malloc(length * sizeof *test1->test2); 
test1->test2->smallstruct = malloc(length * sizeof *test1->test2->smallstruct); 
test1[1].test2[0].smallstruct[1].smallstruct = 123; 
int num = test1[1].test2[0].smallstruct[1].smallstruct; 
1

essayer de changer:

struct s_test1 *test1 = (struct s_test1 *) malloc(sizeof test1); 

à

struct s_test1 *test1 = (struct s_test1 *) malloc(sizeof struct s_test1); 

test1 est un pointeur qui, dans des environnements de 32 bits est de 4 octets.

+0

Mieux vaut: malloc (sizeof * test1); –

1

Vous n'êtes pas allouer de la mémoire pour les struct internes. sizeof (test1) a seulement assez de place pour 3 pointeurs, pas la structure entière des structures.

De plus, cette instruction contient 5 (!) Opérateurs de déréférencement. Même si vous avez alloué suffisamment de mémoire, vous n'avez pas défini les choses de manière à ce qu'elles soient contiguës - vous lui demandez de sauter de bloc en bloc 5 fois.

0

J'ai compilé le code marqué comme correct par l'auteur de la question, @systemsfault, mais j'ai récupéré le core. J'espère avoir une discussion saine et utile ici pour donner la bonne solution à la question. Je suis aussi assez nouveau pour stackoverflow, donc si je dis quelque chose de mal, n'hésitez pas à me corriger. Maintenant, nous y voilà ...

Comme l'ancienne solution ne s'est pas complétée, il y a 2 étapes que j'ai essayé de résoudre. D'abord, j'ai ajouté des boucles, mais j'ai quand même récupéré le noyau causé par (a1) et (a2).

Ensuite, j'ai utilisé les lignes (b1) et (b2) pour remplacer (a1) et (a2). Maintenant, il compilé et fonctionne correctement.

J'ai nettoyé les struct pour le rendre plus simple à lire:

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

struct s_smallstruct{ 
    int smallstruct; 
};      

struct s_test2{ 
    struct s_smallstruct *smallstruct; 
}; 

struct s_test1{ 
    struct s_test2 *test2; 
}; 

int main() { 
    int i, j, length = 2;  

    struct s_test1 *test1 = malloc(length * sizeof *test1); 

    for (i=0; i<length; i++) { 
    //test1[i].test2 = malloc(length * sizeof *test1->test2);//(a1) 
    test1[i].test2 = malloc(length * sizeof *test1[i].test2);//(b1) 

    for (j=0; j<length; j++) { 
     //test1[i].test2[i].smallstruct = malloc(length * sizeof *test1->test2->smallstruct);//(a2) 
     test1[i].test2[j].smallstruct = malloc(length * sizeof *test1[i].test2[j].smallstruct);//(b2) 
    } 
    } 

    test1[1].test2[0].smallstruct[1].smallstruct = 123; 
    int num = test1[1].test2[0].smallstruct[1].smallstruct; 
    printf("num:%d\n", num); 
    return 0; 
}