Peker til å konstruere innenfor de nestede structs

stemmer
3

Jeg prøver å kjøre følgende kode (i GCC 4.3 på Fedora 11 i586):

#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;
}

Men jeg fikk en segfault på test1-> test2 [0] .smallstruct [0] .smallstruct = 123; . Kommen del kjører uten feil. Hva er årsaken til denne oppførselen. Jeg er ikke veldig dyktig i C, så jeg ville sette pris på noen form for hjelp.

Publisert på 26/07/2009 klokken 21:44
kilden bruker
På andre språk...                            


4 svar

stemmer
7

Det er tre problemer med koden som jeg kan se:

  1. sizeof bare forteller deg størrelsen på pekeren, som er 4 for 32-bits pekere, ikke størrelsen på struktur som er pekt på,
  2. og selv om du endrer sizeof å fortelle deg størrelsen på strukturen, malloc vil bare tildele minne for s_test1 struktur, ikke for strukturer som er pekt til fra i det,
  3. og til slutt, pekere i test1 , test2 etc. må klargjøres.

Her er noe som fungerer:

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;
Svarte 26/07/2009 kl. 21:52
kilden bruker

stemmer
1

Du er ikke fordele noe minne for de indre structs. sizeof (test1) har bare plass til 3 pekere, ikke hele struct av structs.

I tillegg har den uttalelsen 5 (!) Dereferanseoperatorene i den. Selv om du hadde bevilget en stor nok del av minnet, har du ikke lagt ut ting på en måte som sikrer det er sammenhengende - du ber den hoppe fra blokk til blokk 5 ganger.

Svarte 26/07/2009 kl. 21:55
kilden bruker

stemmer
1

Prøv å endre:

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

til

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

test1 er en peker, som i 32-biters miljøer er 4 bytes.

Svarte 26/07/2009 kl. 21:51
kilden bruker

stemmer
0

Jeg kompilerte koden merket med riktig valgt av spørsmålet plakat, @systemsfault, men fikk kjernen dumpet. Jeg håper å ha en sunn og nyttig diskutere her for å gi den riktige løsningen for spørsmålet. Jeg er også ganske ny på Stackoverflow, så hvis jeg sier noe feil, kan du gjerne korrigere meg. Nå, here we go ...

Siden den gamle løsningen ikke complile, det er 2 skritt jeg prøvde å fikse det. Først tilsettes jeg for sløyfer, men fortsatt har kjernen dumpet forårsaket av (a1) og (a2).

Deretter brukte jeg linjer (b1) og (b2) å erstatte (a1) og (a2). Nå kompilert det og kjører riktig.

Jeg har ryddet opp structs å gjøre det simplier å lese:

#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;
}
Svarte 28/04/2015 kl. 05:09
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more