how to print memory bits in c

I'm learning how numbers are represented in memory. I want to know how to print the actual representation (binary or hexadecimal) in memory of some int and float variables.

I'd like to see what happens with that numbers when adding or subtracting it causes overflow, for example.

How can I access memory and print it?


Solution 1:

You would need to assign a pointer to the variable in question to a char *, and treat it as an array of bytes of length sizeof(variable). Then you can print each byte in hex using the %X format specifier to printf.

You can define a function like this:

void print_bytes(void *ptr, int size) 
{
    unsigned char *p = ptr;
    int i;
    for (i=0; i<size; i++) {
        printf("%02hhX ", p[i]);
    }
    printf("\n");
}

And call it like this:

int x = 123456;
double y = 3.14;
print_bytes(&x, sizeof(x));
print_bytes(&y, sizeof(y));

Solution 2:

... to print the actual representation (binary ...

To convert any variable/object to a string that encodes the binary form uses a helper function that converts memory into a "binary" string. This method also handles function pointers. Uses C99 or later.

#include <stdio.h>
#include <assert.h>
#include <limits.h>

//                                    .... compound literal .......
#define VAR_TO_STR_BIN(x) obj_to_bin((char [sizeof(x)*CHAR_BIT + 1]){""}, &(x), sizeof (x))

char *obj_to_bin(char *dest, void *object, size_t osize) {
  const unsigned char *p = (const unsigned char *) object;
  p += osize;
  char *s = dest;
  while (osize-- > 0) {
    p--;
    unsigned i = CHAR_BIT;
    while (i-- > 0) {
      *s++ = ((*p >> i) & 1) + '0';
    }
  }
  *s = '\0';
  return dest;
}

int main(void) {
  int i = 42;
  double d = 3.1415926535897932384626433832795;
  printf("Sample\ndouble pi:%s\nint 42:%s\n", VAR_TO_STR_BIN(d), VAR_TO_STR_BIN(i) );
  return 0;
}

Output (Note: depending in endian-ness, results may vary)

Sample
double pi:0100000000001001001000011111101101010100010001000010110100011000  
int 42:00000000000000000000000000101010

This approach is easy to adapt to hexadecimal form.

Solution 3:

Let's say you have a int variable called memory. Make sure you see how many bits it is; for many processors an int is 32 bits as well as a memory address. So you need to loop through each bit, like this:

unsigned int memory = 1234;
for (int i = 0; i < 32; i++)
{
  printf("%d ", memory >> i & 1);
}

This simple method ORs each bit with 1 and shifts each bit by 1.

Solution 4:

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

void print_bits ( void* buf, size_t size_in_bytes )
{
    char* ptr = (char*)buf;

    for (size_t i = 0; i < size_in_bytes; i++) {
        for (short j = 7; j >= 0; j--) {
            printf("%d", (ptr[i] >> j) & 1);
        }
        printf(" ");
    }
    printf("\n");
}

int main ( void )
{
    size_t n;
    scanf("%d", &n);
    print_bits(&n, sizeof(n));
    return 0;
}

This prints bits of the specified object (n here) with the specified size (in bytes).

Solution 5:

@dbush, @Anton, I mixed your codes. It's okay?

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

void print_bytes( void *ptr, size_t size ) ;

int main( void )
{
    int x = 123456 ;
    double y = 3.14 ;

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

    return 0 ;
}

void print_bytes( void *ptr, size_t size )
{
    //char *buf = (char*) ptr;
    unsigned char *p = ptr ;

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

    for( size_t i = 0; i < size; i++ )
    {
        for( short j = 7; j >= 0; j-- )
        {
            printf( "%d", ( p[i] >> j ) & 1 ) ;
        }
        printf(" ");
    }
    printf("\n");
}