2

I'm trying understand how one can access more of memory by typecasting. From watching this video...

https://www.youtube.com/watch?v=ldN5i6MMquM

It sounds like I can typecast a pointer to uint16_t to access 2 parts of a 8 bit addressed memory array. I can't seem to access more than 8 bits and I'm not sure how to write it in c in order to be able to access two bytes instead of one. I started out with something like below

    uint8_t *memory = (uint8_t*) malloc(8);
    memory[0] = 5;
    memory[1] = 21;
    memory[2] = 4;
    memory[3] = 9;
    memory[4] = 23;
    memory[5] = 66;
    memory[6] = 211;
    memory[7] = 46;
cpd1
  • 777
  • 11
  • 31
  • 6
    [Don't ever cast the result of `malloc`](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – user703016 Apr 28 '14 at 12:04
  • 1
    "not sure what to do from there"... Well, what *do* you want to do? What is the purpose of the `memory` "array"? What problem are you trying to solve? – Some programmer dude Apr 28 '14 at 12:06
  • 2
    And note that type-casting has nothing to do with accessing memory. You can allocate memory for any purpose and assign the pointer returned by `malloc` to any kind of pointer. – Some programmer dude Apr 28 '14 at 12:07
  • From what I understand, a value can be stored across memory so that it takes up several address. I want to be able to access more than just the one byte as the video mentions. I'm just not sure how that is able to be implemented – cpd1 Apr 28 '14 at 12:12
  • The video shows you how to cast the `uint8_t *` to a `uint16_t *`. What is it you aren't understanding? – alk Apr 28 '14 at 12:49
  • In my program I can not access more than 8 bits even though I have type casted to uint16_t*. I was hoping to see it fleshed out more in code vs theory – cpd1 Apr 28 '14 at 12:50
  • "*... even though I have type casted to uint16_t.*" You do not show us this part of your program. – alk Apr 28 '14 at 12:51
  • I edited the text but I'll try to add more when I get to work – cpd1 Apr 28 '14 at 13:14

3 Answers3

0

If you already have definitions of all uintXX_t types and an array of bytes like this

uint8_t bytes[8]; 
uint32_t *p3 = (uint32_t *)&bytes[4];
uint8_t *p = bytes;
uint16_t *p1 = (uint16_t *)bytes;
uint32_t *p2 = (uint32_t *)bytes;

                     | uint32_t *p3: accesses a 32bit value starting at bytes[4]
                     v
 bytes: [0][1][2][3][4][5][6][7]
         ^
         | uint8_t *p: can access bytes[0] 
         ^
         | uint16_t *p1: can access 16bits (2 bytes) [0][1]
         ^ 
         | uint32_t *p2: can access 32bits (4 bytes) [0][1][2][3]

and so on. You can also define a struct like this:

struct A { uint8_t x, uint16_t y; };
struct A *ps = (struct A *)bytes;

Then ps will 'see' your bytes array as a struct of type A and you can access the values like this:

 uint8_t x = ps->x; // bytes: [0]
 uint16_t y = ps->y; // bytes: [1][2]

After you understand this, read up on structure member alignment :)

DNT
  • 2,356
  • 14
  • 16
  • Thank you! Explanation is helpful. If I wanted to see the value of p1, I would just do this? printf("%d", *p2); And I would get the value of both bytes combined? – cpd1 Apr 28 '14 at 12:58
  • %d requires an integer (typically 32bits) on the stack - p2 is uint32, so you can use it. If you want the unsigned value use %u instead of %d. – DNT Apr 28 '14 at 12:58
0

In the video you have mentioned, he is not really allocating memory. All that is being explained that if the pointer type is uint8_t, the pointer points to a memory location 8 bits long.
If the pointer is now type casted to point to a unit16_t, it now points to a memory location 16 bits long. That is equivalent to two 8 bit locations.

It does not conjure more memory out of your memory. It simply addresses a larger range of addresses than before.

Sinstein
  • 887
  • 11
  • 42
  • Right I know that. The problem is that I wanted to see it in practice as I can't seem to implement in code properly. When I do it, I only can access 8 bits even though I've typecasted to 16 – cpd1 Apr 28 '14 at 12:52
0

Just define another 16 bit pointer, assign it to the same address

  uint16_t* memory16 = (uint16_t*)memory;

Now you can look at each two 8 bit elements of your memory, like one 16 bit ellement

  for(i = 0; i< 4; ++i)
      printf("%d  ", memory16[i]);  

and feel the difference

 for( i = 0; i< 8; ++i)
     printf("%d  ", memory[i]);
Dabo
  • 2,371
  • 2
  • 18
  • 26
  • Thank you Dabo. That's helpful. I'll have to mess with that when I get back from work. – cpd1 Apr 28 '14 at 12:59