Pourquoi l'adresse de données char affiche pas?
class Address {
int i ;
char b;
string c;
public:
void showMap ( void ) ;
};
void Address :: showMap ( void ) {
cout << "address of int :" << &i << endl ;
cout << "address of char :" << &b << endl ;
cout << "address of string :" << &c << endl ;
}
La sortie est:
address of int : something
address of char : //nothing, blank area, that is nothing displayed
address of string : something
Pourquoi?
Une autre chose intéressante: si l'int, char, string est en public, alors la sortie est
... int : something
... char :
... string : something_2
something_2 - something
est toujours égal à 8. Pourquoi? (pas 9)
Vous devez vous connecter pour publier un commentaire.
Quand vous prenez l'adresse de b, vous obtenez
char *
.operator<<
qui interprète comme une chaîne C, et essaie d'imprimer une séquence de caractères à la place de son adresse.essayer
cout << "address of char :" << (void *) &b << endl
à la place.[EDIT] Comme Tomek a commenté, un plus bonne de fonte à utiliser dans ce cas est
static_cast
, qui est une alternative plus sûre. Voici une version qui utilise à la place du style C cast:b
est. Mais en C++ cast vous offre plus de sécurité lors deb
n'est pas ce que vous pensez qu'il est; un C cast sera juste aveuglément ce que vous dites, sans vraiment se soucier de qui est ungood.&
pourrait avoir été en surcharge (si vous n'obtenez pas "l'adresse"), ou vous pourriez être en train de faire quelque chose oùconst
/volatile
-correction des questions, ou, ou, ouIl y a 2 questions:
Impression pointeurs imprimer l'adresse de la
int*
et lastring*
mais n'imprime pas le contenu pourchar*
comme il ya une surcharge enoperator<<
. Si vous voulez l'adresse, puis utiliser:static_cast<const void *>(&c);
int
et lastring
est8
Sur votre plate-forme
sizeof(int)
est4
etsizeof(char)
est1
donc vous devriez vraiment demander pourquoi8
pas5
. La raison en est que la chaîne est aligné sur une limite de 4 octets. Machines fonctionnent avec des mots plutôt que des octets, et un travail plus rapide si les mots ne sont donc pas de "split" quelques octets ici et quelques octets de là. Ceci est appelé alignementVotre système probablement aligne 4-les limites d'octets. Si vous avez un système 64 bits avec les entiers 64 bits, la différence serait de 16.
(Note: un système 64 bits se réfère généralement à la taille d'un pointeur, pas un int. Donc un système 64 bits avec 4 octets int aurait encore une différence de 8 4+1 = 5, mais des tours jusqu'à 8. Si sizeof(int) 8 de 8+1 = 9 mais cette arrondit jusqu'à 16)
Lorsque vous diffusez l'adresse d'un char à un ostream, il interprète cela comme étant l'adresse du premier caractère d'une ASCIIZ "type C" string", et tente d'imprimer le présumé chaîne. Vous n'avez pas de NUL de terminaison, de sorte que la sortie va continuer d'essayer de lire à partir de la mémoire jusqu'à ce qu'il arrive à trouver l'un ou l'OS, il s'arrête pour essayer de lire à partir d'une adresse non valide. Toutes les ordures qu'il balaye sera envoyé à votre sortie.
Vous pouvez probablement obtenir pour afficher l'adresse que vous souhaitez par la coulée, comme dans
(void*)&b
.Re les décalages dans la structure: - vous observé la chaîne est placée à la position 8. C'est probablement parce que vous avez 32 bits entiers, puis un 8-bit char, alors le compilateur choisit d'insérer 3 plus de 8 bits caractères à ce que la chaîne de l'objet sera aligné à un mot de 32 bits limite. De nombreux Cpu/mémoire d'architectures besoin de pointeurs, ints, etc. pour être sur mot-taille de limites pour effectuer des opérations efficaces sur eux, et, autrement, auraient à faire beaucoup plus d'opérations de lire et de combiner plusieurs valeurs de la mémoire avant de pouvoir utiliser les valeurs d'une opération. Selon votre système, il se peut que chaque objet de classe doit commencer sur une frontière de mot, ou il se peut que
std::string
en particulier commence avec un size_t, pointeur ou d'un autre type que nécessite un tel alignement.Parce que quand vous passez un
char*
àstd::ostream
il imprime le style C (ie: char tableau,char*
) chaîne de il points de.Rappelez-vous que
"hello"
est unchar*
.const char[6]
.char[6]
et se désintègre enchar*
lorsqu'il est utilisé.char[6]
seulement en C, en C++ il estconst char[6]
. Curieusement, il peut encore se désintègrent enchar *
si (rétro compatibilité avec le C).L'adresse de char est traité comme un nul de terminaison de chaîne et est d'afficher le contenu de ce discours, qui n'est probablement pas défini, mais dans ce cas, une chaîne vide. Si vous avez jeté les pointeurs pour
void *
, vous obtiendrez les résultats que vous désirez.La différence entre something2 et quelque chose d'8 est due à alignées et la capacité de le compilateur de décider pour lui-même, où dans la pile les variables sont déclarées.
b = 0
donc automatiquenull
résiliation ? Aussi +1Pour la deuxième question - le compilateur par défaut pad membres de structure. La valeur par défaut dpa est pour le
sizeof(int)
, 4 octets (sur la plupart des architectures). C'est pourquoi uneint
suivie par unchar
8 octets dans la structure, de sorte que lestring
membre est à l'offset 8.Pour désactiver le remplissage, utiliser
#pragma pack(x)
, où x est le tampon de la taille en octets.int
à 4 octets.sizeof(int)
- le natif du PROCESSEUR de la taille. Sur un 32 bits PROCESSEUR c'est 4 octets.int
est à partir de l'adresse 0 à 3. Lechar
devrait être de 4 à 5, mais à la place est de 4 à 7. Enfin, lestring
commence à partir de 8.sizeof(int)
est toujours de 4.char
est à 4 octets. Octets 5 à 7 sont rembourrage, ne fait pas partie de lachar
, qui, par définition, asizeof(char)==1
. Je faisais allusion à un décalage de 5 par rapport au début de l'affichage de l'objet.sizeof(long)
sur le même matériel qui est différent entre fonctionnant sous linux 64 bits et 64 bits de windows.)char
n'est pas rembourré. L'affichage de l'objet est rembourré et le rembourrage (de trois octets) est inséré après lechar
.cstdint
si une question de taille.sizeof(unsigned char) == sizeof(signed char) == sizeof(char) == 1
.Votre syntaxe devrait être
hrnt est à droite sur la raison de la vierge:
&b
a typechar*
, et donc qui sera imprimé comme une chaîne de caractères jusqu'à ce que le premier zéro octet. Sans douteb
est de 0. Si vous définissezb
, par exemple, 'A', alors vous devriez vous attendre l'impression d'être une chaîne de caractères commençant par " A " et en continuant avec les ordures jusqu'à la prochaine zéro octet. Utilisationstatic_cast<void*>(&b)
de l'imprimer en une adresse.Pour votre deuxième question,
&c - &i
est de 8, car la taille d'un int est de 4, le char est 1, et la chaîne commence à la prochaine limite de 8 octets (vous êtes probablement sur un système 64 bits). Chaque type a un particulier, l'alignement, et le C++ permet d'aligner les champs dans la structure selon elle, l'ajout d'un rembourrage de façon appropriée. (La règle de base est que l'ébauche d'un nouveau champ de taille N est aligné à un multiple de N.), En particulier, vous pouvez ajouter 3char
champs aprèsb
sans affecter l'adresse&c
.