Unable to extract byte array value from int value

A union is defined, and given an integer value. The required size of array is estimated. Following the value is defined to the union. However, the byte array values are not able to be printed (ie. the last portion of the following code is not printing). Given:

union {
   unsigned int integer;
   //unsigned char byte[4];
   unsigned char* byte;
} foo;

In main()

int i;

int numberOfBytes = 1;
int targetValue = 123456789;
int sum = 0;
sum = pow(16, numberOfBytes);

while (sum < targetValue) {
    //printf("Trying value: %d \n", (16^numberOfBytes));
    numberOfBytes++;
    sum += pow(16, numberOfBytes);
}
numberOfBytes++; // add 1 more byte space
printf("Number of Bytes: %d \n", numberOfBytes);
printf("Sum: %d \n", sum);


foo.byte = malloc(sizeof(unsigned char)*numberOfBytes);

if (foo.byte == NULL)
    printf("malloc fail\n");

// clear foo
for (i=numberOfBytes; i >= 0;i--) {
    foo.byte[i] = 0;
}

foo.integer = targetValue;
printf("Trying value: %d \n", foo.integer);

The following is not printing:

for (i=numberOfBytes; i >= 0;i--) {
    printf("%x ", foo.byte[i]);
} printf("\n");

Upvotes: 0

Views: 111

Answers (1)

harmic
harmic

Reputation: 30597

In your union, foo.byte is a pointer to an area of memory. This:

foo.byte = malloc(sizeof(unsigned char)*numberOfBytes);

is setting foo.byte to a pointer to an area of memory which you dynamically allocated. Then this:

foo.integer = targetValue;

is overwriting that pointer with the value.

Then this:

for (i=numberOfBytes; i >= 0;i--) {
    printf("%x ", foo.byte[i]);
} printf("\n");

is going to try to de-reference the value of targetValue, which would probably give you a segfault.

The thing is, since you declared targetValue as an int, it will always be sizeof(int) bytes long. There is no reason to dynamically allocate it.

You can change your struct to:

union {
   unsigned int integer;
   unsigned char byte[sizeof(int)];
} foo;

I assume what you are trying to do is figure out the minimum number of bytes to encode the value of targetValue, and create a union of exactly that size.

Another thing to understand about unions is that they always take the amount of space of their largest member, so even if do dynamically allocate the union, you would have to make it at least sizeof(int) long, otherwise you would corrupt adjacent memory whenever you wrote to the int.

Probably you need to rethink what you are trying to do and approach it from a different angle.

Upvotes: 2

Related Questions