Yuanbo
Yuanbo

Reputation: 41

what is the mechanism of the c language storing array in memory

I am learning c language and practicing myself. I am wondering how the c allocate memory for an array. Because I have a code like this:

#include<stdio.h>

int main(void)
{
     char a[] = {1,2,3,4,5,6,7,8,9,10};
     int i = 578;
     char * p1;
     int * p2;
     printf("\nAddress of pointer p1 : %p", &p1);
     printf("\nAddress of pointer p2 : %p", &p2);
     printf("\nAddress of int i : %p", &i);
     p1 = 0x0028FF34;
     p2 = 0x0028FF35;
     /* Print the Addresses */
     for (i = 0; i < 10; i++)
     {
          printf("\nAddress of a[%d] : %p", i, (void *) &a[i]);
     }
     printf("\nThe content in the address 0x0028FF34: %x", *p1);
     printf("\nThe content in the address 0x0028FF35: %x", *p2);
     return 0;
}

Run this code on my computer gives the output like this

Address of pointer p1 : 0028FF2C
Address of pointer p2 : 0028FF28
Address of int i : 0028FF30
Address of a[0] : 0028FF36
Address of a[1] : 0028FF37
Address of a[2] : 0028FF38
Address of a[3] : 0028FF39
Address of a[4] : 0028FF3A
Address of a[5] : 0028FF3B
Address of a[6] : 0028FF3C
Address of a[7] : 0028FF3D
Address of a[8] : 0028FF3E
Address of a[9] : 0028FF3F
The character content in the addresss 0x0028FF34: ffffff80
The character content in the addresss 0x0028FF35: 3020100

The character pointer p occupies 32 bits, which is 4 bytes. Thus the distance of pointer p2 from pointer p1 is 4 bytes long, and so as well the pointer p1 from int i. And int i is also 4 bytes in my systems. In my opinion, the distance of int i from array a[] should be 4 bytes. The starting address of array a[] should be 0028FF34, why it is 0028FF36?

What does the content of 0028FF34 and 0028FF35 mean? The 0028FF34 points to a character, the output is ffffff80 and the 0028ff35 points to an int, the output is 3020100.

Upvotes: 0

Views: 209

Answers (2)

phonetagger
phonetagger

Reputation: 7873

You're wondering how C allocates memory for an array... and other data types. OK. Well, it depends on how the array (or other variable) is defined. In your case, you've defined them as automatically allocated ("local") variables, so they're stored on the C runtime stack. (Technically there could be another allocation mechanism for variables with automatic storage, but in practice most systems use a runtime stack.) If you defined the array & the other variables a few lines up, above int main(void), they would be "global variables" and would be allocated statically and with external linkage so they would be visible to other compilation units (other .c files). And if you put the keyword staticin front of them, they would still be allocated statically but their linkage would be internal, so they would not be visible to other compilation units (.c files). That last part is true whether you define the variables inside or outside of a function body; if you define them as static outside a function body, they're available to other functions in that same compilation unit; if you define them as static inside a function body, the compiler only allows that one function to access them; in fact, they're visible only the scope in which they're defined.

As far as where exactly they're placed, the compiler/linker is free to place them anywhere within their storage class's region that it chooses; in this case, the compiler is placing them on the runtime stack, but their order and relative locations is not defined by the language, so the compiler is free to arrange them in any way it likes.

Often variables will be allocated with padding between them to ensure that they're aligned so that they start on an optimal boundary for their data size because (due to hardware issues) it's often faster to access data on byte boundaries that match their data width, which is exactly what's happening here. You might say, "But i ends on a 4-byte boundary, and a[] has no alignment requirements, so why would it have added padding after i before it allocated a[]?" But that's because you're thinking of allocations occurring in order of increasing memory address. Did you notice that it looks like your variables are allocated in memory "backwards"? Actually they're not! On most systems, the stack grows in memory from high addresses toward low addresses. With that in mind, it's clear that the first variable of your set of variables which was allocated is a[], followed by i (at a lower address). Because the byte address following a[] was not a multiple of 4, before the compiler allocated i, it added 2 bytes of padding!

Now, as to the values you're reading at 0x0028FF34 and 0x0028FF35: Whatever's there is just garbage left over from whatever was last written to those addresses. The byte at 0x0028FF34 is 0x80, which is passed to 'printf()' via ... varargs as an integer, and on your system char must be signed, so when it's promoted to an integer it's sign-extended, and since the high bit of 0x80 is 1, the resulting value is 0xFFFFFF80. The integer you read as 0x0028FF35 shows that the byte at that address is 0x00, and the other bytes are 03, 02, and 01, which you should notice are the first 3 bytes of a[]. We can also tell from this that your system is little-endian (like x86), since the high-order byte of the integer is in the higher byte-addressable location.

Upvotes: 1

Barmar
Barmar

Reputation: 780818

There's no requirement that variables variables be allocated contiguously.

Most datatypes need to be aligned at addresses that are multiples of 4 (and in some cases 8). The exception is char, which doesn't require any special alignment.

The int and pointer variables were allocated contiguously with 4-byte alignment, as you noticed (although it's interesting that they were allocated in a different order from the declarations).

The char array was allocated after it, and uses 10 bytes. There's most likely other internal data in the stack that uses the memory after the array, and it needs 4-byte alignment. So there will be 2 wasted bytes somewhere -- it could be before the array or after. The compiler chose to put it before the array.

Upvotes: 0

Related Questions