0

I'm working on a project and I need to access an array of unsigned char that represent fonts for LCD. Some fonts need two to three bytes to represent each row. So I was trying to implement code like this

const unsigned char font[]={...};//array of n bytes representing a font.
uint8_t *ptr = (uint8_t*)font;
void lcd_map(){
    //get 4 bytes of array as int to map LCD
    int val = *(int*)ptr;
}

Dereferencing the pointer as int isn't working, debugging the code leads to an exception of type illegal access of address.

After some experimentation, I got it working when the assignment of the pointer and the dereferencing are done in the same scope:

const unsigned char font[]={...};//array of n bytes representing a font.
uint8_t *ptr;
void lcd_map(){
    //get 4 bytes of array as int to map LCD
    ptr = (uint8_t*)font;
    int val = *(int*)ptr; 
}

But I need to implement the function as the former code. What may be the issue? I tested the former code on an online C compiler and it works without a problem.

  • 1
    My general advice is to not pigeon-hole yourself into one implementation. That becomes an X/Y problem for the community. Instead, state your intent and show what you've done. Then, you'll likely get better advice and learn other ways of tackling the problem. – Rafael Jun 23 '21 at 01:29
  • *Dereferencing the pointer as `int` isn't working* Because doing that is always [a strict aliasing violation](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) and undefined behavior. Whoever taught you to write code like that doesn't really understand C. You can't treat memory as something it's not (except you can always treat anything as `[un[signed]] char`). In this case you're trying to treat memory that's actually `unsigned char` as an `int`. **You can't do that safely**. Full stop. Anyone who tells you otherwise is just plain wrong. – Andrew Henle Jun 23 '21 at 02:09
  • `const unsigned char font[]` lacks certain `int` alignment. Step 1: fix that per @Rafael. – chux - Reinstate Monica Jun 23 '21 at 02:54
  • Thank you, I wasn't thinking about the strict aliasing. Instead, I used `memcpy()` and problem solved. – Bruno Leppe Jun 23 '21 at 04:24

1 Answers1

1

My advice is to create a union that allows you to access the individual bytes as well as the 4-byte whole:

union {
        uint32_t whole;
        uint8_t parts[4];
} font;

void lcd_map(void)
{
        uint32_t data = font.whole;
        uint8_t byte2 = font.parts[1];
}
Rafael
  • 7,605
  • 13
  • 31
  • 46