3

I have an array and I want to convert it to an int32_t array.

I tried the code below.

int32_t const_data[11];
int8_t buffer[44];

    int k = 0;
    while (k < 11) {
        for (int j = 0; j < 44; j++) {
                const_data[k] = bf.buffer[j];
                k++;
        }
    }
6
  • 2
    In what endian form? Bytes and multi-byte integers are not necessarily interchangeable. Commented Jun 19, 2019 at 16:25
  • 1
    How is that code supposed to work? It appears to be unrelated to your stated aim. What is size_of_const() and what is the +12 offset for? Also 0001 0004 0003 is not an unambiguous description of the content - 4 digit octal values suggests 12 bit value not uint8_t - or are these character strings representing integers and not 8 bit integers at all? Too much ambiguity to post an answer. Commented Jun 19, 2019 at 16:28
  • @Clifford good point about the octal values but I assume he meant 0x0001, 0x0004, etc Commented Jun 19, 2019 at 16:52
  • 1
    But even then those would be 16 bits.. Commented Jun 19, 2019 at 16:54
  • Are you just trying to get the compiler to treat buffer as int32_t*? In this case just cast:int32_t* const_data = (int32_t*) buffer Commented Jun 19, 2019 at 17:43

2 Answers 2

4

The easiest and most straight forward way is to use a union

#define array_size_int32    11
#define array_size_int8     44

typedef union{
    int32_t const_data[array_size_int32];
    int8_t buffer[array_size_int8];
}my_union_t;

Example usage:

/* initialize union members */
my_union_t my_union = {
    .const_data = {
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
        0x12345678,
    },
};

Example way to print:

uint8_t i;

for(i = 0; i < array_size_int8; i++){

    /* mask off sign extension bits */
    printf("my_union.buffer[%d] = %x\n", i, my_union.buffer[i] & 0xff);

}

You can try the code out here

EDIT:

I should add that this works because the memory size needed to allocate either array is the same and you'll run in to problems if you change the #define's without taking that in to consideration.

For example,

#define array_size_int32    10    //40 bytes
#define array_size_int8     45    //45 bytes
Sign up to request clarification or add additional context in comments.

3 Comments

So this converts my byte_t array to word_t array but in an opposite way. So if byte_t array is 00 00 00 04. Then my word_t array becomes 40000000. How can I fix this so that my word_t array can be 00000004. Thank you!
It's actually 04 00 00 00. When you are printing, it doesn't show you the leading zero unless you specify it to do so (e.g. printf("%08x\n", my_union.const_data[0]);) And this has to do with endianness. I'll explain more in the following comment.
If 0x00000004 is your 32 bit value for my_union.const_data[0], then 0x04 is the least significant byte, and on a little endian machine this will get stored in the lowest position of my_union.buffer (position 0). If you set my_union.buffer[0] = 0x00, my_union.buffer[1] = 0x00, my_union.buffer[2] = 0x00, my_union.buffer[4] = 0x04, then my_union.const_data[0] is going to print 0x04000000 because 0x04 is actually the most significant byte. If you want 0x04 to be the least significant byte, then store it at my_union.buffer[0].
-1

Below is solution which I used in past for similar problem.

#include <stdio.h>
#include <inttypes.h>
int main(){
    int8_t input[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
    int32_t output[10];
    int count=0;
    for(;count<sizeof(input);count+=sizeof(int32_t)/sizeof(int8_t)){
        output[count] = (int32_t)(*(int32_t*)(&input[count]));
        printf("%x:%x\n",input[count],output[count]);
    }
    return 0;
}

Note: As pointed out by @tadman in comment. You also need to consider endianness of your platform. This solution works well for my problem on platform I was working. Based on your platform you may need to tweak this.

Live Code

4 Comments

I forgot to men that it is in C :(
@bigwillydos thanks for pointing out my mistake. Updated for c.
output[count] = (int32_t)(*(int32_t*)(&input[count])); is a strict aliasing violation and is likely to be a misaligned access. Both of which are undefined behavior. You can not safely take a character address and treat it like another type - int32_t in this case.
@ManthanTilva cool, removed the downvote since you corrected that, however, I have not actually reviewed your answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.