tags:

views:

226

answers:

4

In C, in an Unix environment (Plan9), I have got an array as memory.

uchar mem[32*1024];

I need that array to contain different fields, such as an int (integer) to indicate the size of memory free and avaliable. So, I've tried this:

uchar* memp=mem;
*memp=(int)250; //An example of size I want to assign.

I know the size of an int is 4, so I have to force with casting or something like that, that the content of the four first slots of mem have the number 250 in this case, it's big endian.

But the problem is when I try to do what I've explained it doesn't work. I suppose there is a mistake with the conversion of types. I hopefully ask you, how could I force that mem[0] to mem[3] would have the size indicated, representated as an int and no as an uchar?

Thanks in advance

+2  A: 

Like this:

*((int*) memp) = 250;

That says "Even though memp is a pointer to characters, I want you treat it as a pointer to integers, and put this integer where it points."

RichieHindle
Ok, thanks, it does work. And I've got the point.
Polar Geek
But, if I want to assign a pointer to another part of mem (the array of unsigned chars),at the beginning to nil. Could I do something like this?:*((void*) memp) = nil;It doesn't compile. :(
Polar Geek
It is never possible to dereference a (void *) pointer.
ephemient
Be careful when attempting to write things other than char/uchar to a uchar array, unless you know the address is aligned properly (i.e. for a 32-bit system, usually aligned to a 4-byte boundary). Many modern processors can handle unaligned writes (with a performance penalty -- and note that the compiler may assume the worst and use slower instructions to make the write), but some still can't -- see e.g. smaller processors like the early ARMs. You also may have aliasing issues to worry about...
leander
A: 

Cast pointer to int, not unsigned char again!

int * memp = (int *)mem;
* memp = 250; //An example of size I want to assign.
dragonfly
+2  A: 

Have you considered using a union, as in:

union mem_with_size {
  int   size;
  uchar mem[32*1024];
};

Then you don't have to worry about the casting. (You still have to worry about byte-ordering, of course, but that's a different issue.)

JamieH
+1  A: 

As others have pointed out, you need to cast to a pointer to int. You also need to make sure you take alignment of the pointer in consideration: on many architectures, an int needs to start at a memory location that is divisible by sizeof(int), and if you try to access an unaligned int, you get a SIGBUS. On other architectures, it works, but slowly. On yet others, it works quickly.

A portable way of doing this might be:

int x = 250;
memcpy(mem + offset, &x, sizeof(x));

Using unions may make this easier, though, so +1 to JamieH.

Lars Wirzenius