Je commençais un petit jeu avec C++ aujourd'hui et je suis tombé sur ce que je pensais être étrange, mais peut-être plus probablement en raison d'un malentendu de ma part et du manque de codage C pur récemment. Ce que je cherchais à faire à l'origine était de convertir un double en un tableau de caractères non signés. Ma compréhension était que les 64 bits du double (sizeof (double) est 8) seraient maintenant représentés comme 8 caractères de 8 bits. Pour ce faire, j'utilisais reinterpret_cast.C++. reinterpret_cast de double à unsigned char *
Voici donc du code pour convertir un tableau en tableau double, ou du moins je pensais que c'était ce qu'il faisait. Le problème était qu'il revenait 15 de strlen au lieu de 8, pourquoi je ne suis pas sûr.
double d = 0.3;
unsigned char *c = reinterpret_cast<unsigned char*> (&d);
std::cout << strlen((char*)c) << std::endl;
Donc le strlen était mon premier numéro. Mais ensuite j'ai essayé ce qui suit et j'ai trouvé que ça a retourné 11, 19, 27, 35. La différence entre ces nombres est de 8 donc à un certain niveau, quelque chose de bien se passe. Mais pourquoi cela ne retourne-t-il pas 15, 15, 15, 15, (comme il revenait 15 dans le code ci-dessus).
double d = 0.3;
double d1 = 0.3;
double d2 = 0.3;
double d3 = 0.3;
unsigned char *c_d = reinterpret_cast<unsigned char*> (&d);
unsigned char *c_d1 = reinterpret_cast<unsigned char*> (&d1);
unsigned char *c_d2 = reinterpret_cast<unsigned char*> (&d2);
unsigned char *c_d3 = reinterpret_cast<unsigned char*> (&d3);
std::cout << strlen((char*)c_d) << std::endl;
std::cout << strlen((char*)c_d1) << std::endl;
std::cout << strlen((char*)c_d2) << std::endl;
std::cout << strlen((char*)c_d3) << std::endl;
J'ai donc regardé les adresses des caractères et ils le sont.
0x28fec4
0x28fec0
0x28febc
0x28feb8
Maintenant, cela fait sens, étant donné que la taille d'un unsigned char * sur mon système est de 4 octets, mais je pensais que le montant exact de la mémoire serait allouée à partir de la distribution, sinon il semble que reinterpret_cast est une jolie chose dangereuse ... En outre, si je
for (int i = 0; i < 4; ++i) {
double d = 0.3;
unsigned char *c = reinterpret_cast<unsigned char*> (&d);
std::cout << strlen((char*)c) << std::endl;
}
imprime 11, 11, 11, 11!
Donc, ce qui se passe ici, clairement la mémoire est écrasée par endroits et réinterpréter la distribution ne fonctionne pas comme je le pensais (c'est-à-dire que je l'utilise mal). Ayant utilisé des chaînes depuis longtemps en C++, parfois quand vous revenez à des tableaux de caractères bruts, vous oubliez ces choses.
Donc je suppose que c'est une question en 3 parties.
Pourquoi strlen a-t-il initialement renvoyé 15? Pourquoi les 4 appels strlen ont-ils augmenté en taille? Pourquoi la boucle a-t-elle renvoyé 11, 11, 11, 11?
Merci.
_casting_ n'attribue aucun espace de stockage. Utiliser 'reinterpret_cast' dit essentiellement au compilateur:" Hey, je sais ce que je fais, faites-moi confiance. " Par conséquent, c'est à vous de connaître l'espace de stockage que ces conversions peuvent indiquer de manière valide. – Chad
@Chad ce genre de réponses ma meilleure question. Comme je l'ai dit dans le commentaire pour la réponse choisie, je m'attendais à trop de casting. Je suis conscient du caractère \ 0, cependant, c'était vraiment le comportement de reinterpret_cast et ce qui m'avait fait un peu confus. –