2013-03-12 3 views
2

amateurs stackoverflow Chers,Trouver l'adresse des variables membres de la structure imbriquée

d'abord tout ce que je suis un novice dans StackOverflow, donc je présenter des excuses à l'avance pour les erreurs que je commets.

Ceci est une sorte de puzzle en C. ou au moins j'ai été intrigué par cela. Le code est donné ci-dessous.

struct outer_str 
{ 
    struct nest_str1 
    { 
    int mem1; 
    }; 
    struct nest_str2 
    { 
    int mem2; 
    }nest_var2; 
}outer_var; 

int main() 
{ 
    outer_var.nest_var2.mem2 = 111; 
    printf("\n\nThe value of mem2 is %d\n\n",outer_var.nest_var2.mem2); 

    // Statement to assign mem1 of nest_str1 with a value say 333; 
    // Statement to print the value of mem1 of nest_str1; 

    return 0; 
} 

Comme les commentaires suggèrent que vous devez accéder à la variable membre mem1 de la structure imbriquée nest_str1. Notez également qu'il n'y a pas de variables de structure déclarées pour la structure imbriquée nest_str1. Espérant contre l'espoir j'ai essayé le code suivant, en imitant un peu de C++.

outer_var.nest_str1.mem1=333; 

Quand je compilé le programme en utilisant GCC 4.6.3, l'erreur suivante a été montré

"struct outer_str has no member named 'nest_str1' ". 

Je pensais à trouver l'adresse de nest_str1 à l'adresse de nest_var2 qui est la structure variable de la structure imbriquée nest_str2. J'ai essayé le code suivant,

int main() 
{ 
int offset; 
struct nest_str1 * addr; 
offset=sizeof(int); // There is only one integer mem1 in nest_str1 
addr=(struct nest_str1 *)((int *) & (outer_var.nest_var2) - offset); 
addr->mem1=333; 
printf("\n\nThe value of mem1 is %d\n\n",addr->mem1); 
return 0; 
} 

Le programme compilé O.K. Mais la sortie n'était pas ce que je m'attendais. J'ai une erreur d'exécution.

Segmentation fault (core dumped) 

Maintenant, je ne sais même pas si mon approche était correcte ou non. J'espère donc avoir quelques suggestions. Je crains également d'avoir oublié une solution apparemment simple.

Je voudrais également savoir si nous pouvons accéder à mem1 dans le code donné ci-dessous.

struct outer_str 
{ 

    struct nest_str1 
    { 
    int mem1; 
    }; 

}outer_var; 

Je remercie chacun d'avance pour votre temps et votre patience.

+1

Certaines personnes ont besoin d'être prudent à ce sujet, parce que la syntaxe ci-dessus est acceptée par certains compilateurs.. Ils considéreraient «nest_str1» comme un membre anonyme (ou non nommé) de la structure et autoriseraient «directement» l'accès à ses membres, comme dans: 'external_var.mem1 = 7;' compilerait bien. portable **! (Ceci a été ajouté juste à titre de référence, car certaines personnes peuvent s'en tirer et d'autres ne le peuvent pas - et il y a beaucoup de lecteurs ici ...) –

+0

@SteveValliere, ce serait le cas si la structure est anonyme, c'est-à-dire non nommé comme ci-dessus. ('struct {int mem1;};') AFAIK – Nim

+0

@Nim la présence de la structure _tag_ n'affecte pas si une _instance_ de la structure est anonyme ou non. Vous pourriez nommer une instance d'une structure sans étiquette, alors vous ne pouvez pas réutiliser la définition de la structure ailleurs (parce que c'est anonyme.) Ce n'est probablement pas clair, désolé. C'est pourquoi j'ai pensé que cela valait la peine de mentionner que les membres anonymes devraient généralement être évités autant que possible - ils sont déroutants et non portables. –

Répondre

2

Il n'y a aucun membre de outer_var qui vous permettra d'accéder à mem1 (vous avez pas déclaré un, vous venez de définir un type appelé nest_str1.)

Modifier ceci:

struct outer_str 
{ 

    struct nest_str1 
    { 
    int mem1; 
    } nest_var1; // now there is a member! 

}outer_var; 

maintenant vous pouvez:

outer_var.nest_var1.mem1 = 100; 

Votre tentative est tout simplement faux, e Il n'y a pas de stockage pour mem1, donc même si votre code fonctionnait, vous finiriez probablement par écrire à l'adresse mem2.

+0

Merci. Mais qu'arrivera-t-il lorsque la variable de structure outer_var de la structure outer_str sera créée? – Deepu

+0

Mais j'ai soustrait le décalage de l'adresse de mem2. – Deepu

+1

D'où le segfault, vous écrivez dans un emplacement de mémoire aléatoire, comme je l'ai dit, il n'y a pas * storage * pour 'mem1', gcc par défaut ne traite pas votre première structure comme une structure * anonyme * (vous l'avez nommée, donc, c'est traité comme un * type *). Supprimez le nom, puis 'mem1' sera accessible à partir de' outer_var' comme 'outer_var.mem1') – Nim

0

Le code que vous avez écrit est absolument exact. Mais en soustrayant la valeur "offset" de la seconde structure imbriquée "outer_var.nest_var2", malgré le typecasting à (int ), il suffit de le transtyper en (char) ie "addr = (struct nest_str1 *) ((char *) & (outer_var.nest_var2) - (char *) offset), » et vous serez en mesure de remplir la variable dans la première structure

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

struct outer_str{ 
     struct nest_str1 
    { 
    int mem1; 
    }; 
    struct nest_str2 
    { 
    int mem2; 
    }nest_var2; 
}outer_var; 

int main() 
{ 
    int offset; 
    struct nest_str1 * addr; 
    offset=sizeof(int); // There is only one integer mem1 in nest_str1 
    addr=(struct nest_str1 *)((char *) & (outer_var.nest_var2) - (char   *)offset); 
    addr->mem1=333; 
    printf("\n\nThe value of mem1 is %d\n\n",addr->mem1); 
    return 0; 
} 
Questions connexes