2009-05-28 4 views
7

Je travaille en suivant une formation C++. Jusqu'ici tout va bien, mais j'ai besoin d'aide pour renforcer certains des concepts que j'apprends. Ma question est comment puis-je visualiser les modèles d'octets pour les objets que je crée. Par exemple, comment est-ce que j'imprimerais le modèle d'octet pour les structs, les longs, les ints etc.? Je comprends cela dans ma tête et je peux comprendre les diagrammes de mon matériel d'étude, j'aimerais simplement pouvoir afficher de façon programmée des modèles d'octets à l'intérieur de certains de mes programmes d'études. Je me rends compte que c'est assez trivial, mais toute réponse m'aiderait grandement dans ces concepts.Comment visualiser les octets avec C/C++

Merci. Editer: J'utilise principalement XCode pour mes autres projets de développement, mais j'ai des VM pour Windows7 et Fedora Core. Au travail j'utilise XP avec Visual Studio 2005. (Je ne peux pas commenter car je suis toujours un n00b ici: D)

J'ai utilisé la solution de unwind qui est à peu près ce que je cherche. Je pense aussi que je pourrais peut-être juste utiliser la commande DOS DEBUG car je voudrais aussi regarder les morceaux pour la mémoire aussi. Encore une fois, c'est juste pour m'aider à renforcer ce que j'apprends. Merci encore les gens!

+0

Vous devez expliquer yourt environnement (compilateur, débogueur si Oyu ont un, OS, etc.) –

+0

Voulez-vous dire informations de débogage afin que vous puissiez voir votre objet chargé en mémoire pendant l'exécution? –

+0

Oui, l'information du débogueur serait grande. – OhioDude

Répondre

24

Vous pouvez utiliser une fonction comme celle-ci, pour imprimer les octets:

void print_bytes(const void *object, size_t size) 
{ 
    // This is for C++; in C just drop the static_cast<>() and assign. 
    const unsigned char * const bytes = static_cast<const unsigned char *>(object); 
    size_t i; 

    printf("[ "); 
    for(i = 0; i < size; i++) 
    { 
    printf("%02x ", bytes[i]); 
    } 
    printf("]\n"); 
} 

Utilisation ressemblerait à ceci, par exemple:

int x = 37; 
float y = 3.14; 

print_bytes(&x, sizeof x); 
print_bytes(&y, sizeof y); 

Cela montre les octets seulement sous forme de valeurs numériques brutes , en hexadécimal, qui est couramment utilisé pour les "dumps mémoire" comme ceux-ci.

Sur un échantillon aléatoire (peut-être même virtuel, pour tout ce que je sais) machine Linux exécutant un "Intel (R) Xeon (R)" CPU, cette impression:

 
[ 25 00 00 00 ] 
[ c3 f5 48 40 ] 

Ce haut la main démontre également que la Intel famille de CPU: s sont vraiment little endian.

+0

Pourquoi devez-vous le convertir en un pointeur char non signé. – user1721803

+0

@ user1721803 Parce que vous ne pouvez pas déréférencer 'void * '. Je pense qu'il est plus propre d'avoir une fonction comme celle-ci accepter un 'const void *', car cela fait * utiliser * la fonction très simple et sans cast. Les castes doivent être évitées, mieux vaut les contenir au besoin au lieu de les infliger aux autres. – unwind

+0

@unwind pourquoi faites-vous cela bit à bit et de chaque octet avec '0xff'? Est-ce nécessaire? –

-1

essayez ceci:

MyClass* myObj = new MyClass(); 
int size=sizeof(*myObj); 
int i; 
char* ptr = obj; // closest approximation to byte 
for(i=0; i<size; i++) 
    std::cout << *ptr << endl; 

Cheers,

HJR.

+0

std :: cout << * ptr ++ << endl; – ralphtheninja

+0

char * ptr = reinterpret_cast (myObj); –

+0

et probablement endl a besoin d'un préfixe std :: – none

5

Si vous utilisez gcc et X, vous pouvez utiliser le DDD debugger pour dessiner de jolies images de vos structures de données.

+0

DDD a réellement une très bonne visualisation. C'est génial quand vous voulez voir une structure de données complexe. Heck, même une liste liée est agréable dans DDD. –

0

Ou si vous avez le coup de pouce lib et que vous voulez utiliser les évaluations lambda, vous pouvez le faire de cette façon ...

template<class T> 
void bytePattern(const T& object) 
{ 
    typedef unsigned char byte_type; 
    typedef const byte_type* iterator; 

    std::cout << "Object type:" << typeid(T).name() << std::hex; 
    std::for_each( 
     reinterpret_cast<iterator>(&object), 
     reinterpret_cast<iterator>(&object) + sizeof(T), 
     std::cout << constant(' ') << ll_static_cast<int>(_1)&&0xFF); 
    std::cout << "\n"; 
} 
+0

Vous n'avez pas mentionné quels morceaux de votre exemple viennent de Boost.Lambda, ce qui peut être difficile à décoder par des programmeurs non expérimentés. Nous y voilà: boost :: lambda :: ll_static_cast, boost :: lambda :: _ 1 – mloskot

1

La plupart (visuels) débogueurs ont une « option « Voir la mémoire. IIRC celui Xcode est assez basique, montrant juste des octets en HEX et ASCII, avec une longueur de ligne variable.Visual Studio (Debug-> Windows-> Memory en Vs2008) peut formater la partie hexadécimale en différentes longueurs entières, ou en virgule flottante, changer l'endianess, et afficher le texte ANSI ou UNICODE Vous pouvez également définir à peu près n'importe quel nombre pour la largeur de la fenêtre (je pense que xcode ne vous laisse que 64 octets) L'autre IDE que j'ai ici au travail a beaucoup d'options, mais pas tout autant que VS.

2

Juste pour être complet, un C++ par exemple:

#include <iostream> 

template <typename T> 
void print_bytes(const T& input, std::ostream& os = std::cout) 
{ 
    const unsigned char* p = reinterpret_cast<const unsigned char*>(&input); 
    os << std::hex << std::showbase; 
    os << "["; 
    for (unsigned int i=0; i<sizeof(T); ++i) 
    os << static_cast<int>(*(p++)) << " "; 
    os << "]" << std::endl;; 
} 

int main() 
{ 
    int i = 12345678; 
    print_bytes(i); 
    float x = 3.14f; 
    print_bytes(x); 
} 
Questions connexes