2009-05-28 13 views
7

Estoy trabajando en mi entrenamiento de C++. Hasta ahora todo va bien, pero necesito ayuda para reforzar algunos de los conceptos que estoy aprendiendo. Mi pregunta es ¿cómo hago para visualizar los patrones de bytes para los objetos que creo? Por ejemplo, ¿cómo imprimiría el patrón de bytes para estructuras, longs, ints, etc.?Cómo visualizar bytes con C/C++

Lo entiendo en mi cabeza y puedo entender los diagramas en mis materiales de estudio, me gustaría poder mostrar programáticamente los patrones de bytes de algunos de mis programas de estudio.

Me doy cuenta de que esto es bastante trivial, pero cualquier respuesta me ayudaría enormemente a dominar estos conceptos.

Gracias.

Editar: Uso principalmente XCode para mis otros proyectos de desarrollo, pero tengo VM para Windows7 y núcleo de fedora. En el trabajo utilizo XP con visual studio 2005. (No puedo comentar porque todavía soy un n00b aquí: D)

Utilicé la solución de unwind, que es lo que estoy buscando. También estoy pensando que quizás podría usar el comando dos DEPURAR ya que también me gustaría mirar fragmentos para memoria también. De nuevo, esto es solo para ayudarme a reforzar lo que estoy aprendiendo. Gracias de nuevo a la gente!

+0

Es necesario explicar yourt medio ambiente (compilador, depurador si oyu tiene uno, sistema operativo, etc.) –

+0

Qué quiere decir información depurador para que pueda ver el objeto cargado en memoria durante el tiempo de ejecución? –

+0

Sí, la información del depurador sería grandiosa. – OhioDude

Respuesta

24

Puede utilizar una función como esta, para imprimir los bytes:

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"); 
} 

uso se vería así, por ejemplo:

int x = 37; 
float y = 3.14; 

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

Esta muestra los bytes como si fueran valores numéricos primas , en hexadecimal que se usa comúnmente para "volcados de memoria" como estos.

En un (incluso podría ser virtual, por lo que sé) máquina Linux aleatoria funcionamiento de una "Intel (R) Xeon (R)" de la CPU, esta impresiones:

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

Este cómodamente también demuestra que la La familia de CPU Intel: s realmente son little endian.

+0

¿Por qué tiene que convertirlo en un puntero de signo sin signo? – user1721803

+0

@ user1721803 Porque no puede quitar la referencia 'void * '. Creo que es más limpio tener una función como esta aceptando un 'const void *', ya que eso hace que * using * la función sea muy simple y sin conversión. Se deben evitar los moldes, mucho mejor para contenerlos donde sea necesario en lugar de infligirlos a los demás. – unwind

+0

@unwind ¿por qué lo haces en bits y de cada byte con '0xff'? ¿Es necesario? –

-1

probar esto:

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,

JRH.

+0

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

+0

char * ptr = reinterpret_cast (myObj); –

+0

y probablemente endl necesita un estándar :: prefix – none

5

Si está utilizando gcc y X, puede usar el DDD debugger para dibujar lindas imágenes de sus estructuras de datos.

+0

DDD en realidad tiene una muy buena visualización. es genial cuando quieres ver una estructura de datos compleja. Diablos, incluso una lista vinculada es agradable en DDD. –

0

O si tiene el lib impulso y desea utilizar las evaluaciones lambda puede hacerlo de esta manera ...

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

No ha mencionado qué bits de su ejemplo provienen de Boost.Lambda, lo que puede ser difícil de descifrar por los programadores no experimentados. Aquí vamos: boost :: lambda :: ll_static_cast, boost :: lambda :: _ 1 – mloskot

1

más depuradores (visuales) tienen una opción de "Ver memoria'. IIRC la de Xcode es bastante básico, solo muestra bytes en HEX y ASCII, con una longitud de línea variable. Visual Studio (Depuración-> Windows-> Memoria en Vs2008) puede formatear la porción hexadecimal como diferentes longitudes enteras, o punto flotante, cambiar la endianess, y muestra texto ANSI o UNICODE. También puede establecer casi cualquier número para el ancho de la ventana (creo que xcode solo le permite ir a 64 bytes de ancho) El otro IDE que tengo aquí en el trabajo tiene muchas opciones, aunque no tantos como VS.

2

simplemente para la corrección, un C++ ejemplo:

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