1

I have an array of unsigned long that I expect to be 4 bytes per array element (32 bits), like this:

unsigned long giantbuffer[1024];

However, when I Print out the address of my array elements I get:

printf("%X\n", &giantbuffer[0]);  --> gives ab8470

printf("%X\n", &giantbuffer[1]);  --> gives ab8478

also,

sizeof(giantbuffer) gives 8192, and sizeof(giantbuffer[0]) gives 8.   

That is eight bytes per array element! Is this something that is dependent on system architecture or something? I am new to C, so maybe this is an obvious thing? This wreaks havoc with my pointer arithmetic. I am using "ch" to do some interpreter command-line style checking of my syntax, etc. Maybe this is a problem with that program?

Hanky Panky
  • 46,730
  • 8
  • 72
  • 95
user2935084
  • 21
  • 1
  • 2
  • 2
    Why do you expect `long` to be 4 bytes long? Any sensible 64-bit architecture/implementation I know of defines `long` as a 64-bit type. (Yes, Win64 does not count as a sensible implementation.) –  Oct 30 '13 at 06:41
  • 1
    If you want an integer of a specific size, use stdint.h – Jonathon Reinhart Oct 30 '13 at 06:43

2 Answers2

4

Because on your environment, the sizeof unsigned long is 8 bytes. Pointer arithmetic depends on the type of object being pointed to:

int i = 10;
int *p_i  = &i;

Incrementing p_i by 1 - increases the pointer with sizeof(int) bytes.

char c = 10;
char *p_c  = &i;

Incrementing p_c by 1 - increases the pointer with sizeof(char) bytes, and so on.

Is this something that is dependent on system architecture or something?

Yes. It also depends on your Compiler and also if the architecture is 32 / 64 bit.

Sadique
  • 22,572
  • 7
  • 65
  • 91
4

If you need a specific amount of bytes for a datatype, don't use types like unsigned long. Instead, check out something like the stdint header.

Instead of:

unsigned long myvar = 0;
unsigned long mybuf[100];

you'd do:

uint32_t myvar = 0;
uint32_t mybuf[100];

and you'll get a 32-bit value wherever you go.

Clarification: Based on your system architecture, uint32_t gets typedef'ed to unsigned int or unsigned long. This is typically handled by use of preprocessor macros as below:

#ifdef __x86_64__
typedef unsigned int uint32_t;
#else
typedef unsigned long uint32_t;
#endif
anishsane
  • 20,270
  • 5
  • 40
  • 73
Nick Veys
  • 23,458
  • 4
  • 47
  • 64