5
typedef struct block
{
   size_t size;
   struct block* next;
} node;

static char arr[1000];

What happens with arr

when I do

node* first_block = (node*)arr;

?

I understand that this is equal to

node* first_block = (node*)&arr[0];

but

sizeof(node) = 8;
sizeof(arr[0])= 1;

so first element override next seven elements in the arr, because it's struct now ? Can you explain me this cast, please ?

  • Note that this may not work properly. `node` requires an alignment greater than what `arr` is required to have. – Bill Lynch Mar 28 '15 at 17:04
  • can you explain this please? –  Mar 28 '15 at 17:17
  • I'm going to use a simpler example: `char x[4]; int32_t *y = &x;` It's possible that `x` has an address like `0x1001`. However, `int32_t` requires an alignment of 4 bytes. The address that `x` has breaks that contract. – Bill Lynch Mar 28 '15 at 17:34
  • If you are really planning to go ahead with this, please consider [using a union instead](http://stackoverflow.com/questions/1821486/union-versus-void-pointer). It has the same effect as casting a pointer (i.e. impose a _different_ compile-time interpretation to the _same_ raw byte data), but in a more structured manner. It also prevents potential alignment issues as raised by Bill Lynch. – Ruud Helderman Mar 28 '15 at 18:07
  • The coolest pointer type cast ever is in the _fast inverse square root_ algorithm. Reading the [Wikipedia article](http://en.wikipedia.org/wiki/Fast_inverse_square_root) may actually help you understand the effect of such a type cast. – Ruud Helderman Mar 28 '15 at 18:34

4 Answers4

7

When you write

node* first_block = (node*)arr;

you are not changing anything in memory, you get a pointer to the area in memory, the type of the pointer determines how the area is treated in regard to pointer arithmetic.

first_block->next will be a pointer that is determined by the characters in the array.

as a comparison say you have a char* pointer to the same array

(if arr is declared at global scope it will contain 0's)

char* q = arr;
node* p = (node*)arr;


                arr[1000]
          +----------------------+
  q  ->   |   |   |          |   |
          | 0 | 0 | ...      | 0 |
  p ->    |   |   |          |   |
          +----------------------+

when you do

q = q + 1;  

// you move the character pointer one char forward since q is a char pointer

when you do

p = p + 1;  

// you move the node pointer sizeof(node) chars forward since p is a node pointer

when you do *q you get the character value of where q points to, *p gives you the node value from the char arr, i.e. the characters are interpreted as a node struct.

AndersK
  • 35,813
  • 6
  • 60
  • 86
  • so when I do p->size = 100; arr[0] = 100; what will be after p->next = 0x123123 ? arr[1] = 0x123123 ? –  Mar 28 '15 at 17:26
  • depends on your architecture (endianness, sizeof int) 100 is 64 hex but easiest is just to print out the value with `printf("%p", p->next);` – AndersK Mar 29 '15 at 16:49
0

It's related to pointer arithmetic, when you have a pointer type *pointer, and you do this

type *next = pointer + 1;

or

type *next = &pointer[1];

you are effectilvely doing this

type *next = ((char *)pointer + sizeof(type));
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
0

nothing happens to the data when the code does a 'cast'. However,

the compiler will treat that data differently for the duration/scope of the cast.

the duration/scope of the cast is (almost always) only the statement that contains the cast.

user3629249
  • 16,402
  • 1
  • 16
  • 17
  • so first 8 byte will be a struct and other(1000 -8) a char ? –  Mar 28 '15 at 17:00
  • No, the scope of the cast is just the line containing the cast. none of the data is changed. It will be the (size of struct) bytes of array will be treated as an instance of the struct, for the duration of that one line of code. Since an array devolves to a pointer, the code act as though that pointer were pointing to an instance of the struct (but only for that one line of code) – user3629249 Mar 28 '15 at 17:05
0

Memory does not know about types, so nothing happens to it when casting. Types in C just describe how the bytes in memory are interpreted.

You can treat a sequence of 8 bytes as 8 ASCII characters (char[8]) or a struct node. Casting just changes the view of the data, but the data is not affected.

Ferdinand Beyer
  • 64,979
  • 15
  • 154
  • 145