Home > Enterprise >  the relationship of arrays and pointers and the storage of this in RAM
the relationship of arrays and pointers and the storage of this in RAM

Time:11-01

I am currently learning arrays in C. In the training that I follow, it is marked two things that cause me problems :

  • The first is that in the RAM each of the boxes that make up the table follows one another
  • The second is that a table is a pointer that points to the first box of the table

Could someone clarify for me about the storage of arrays in RAM and their relationship to pointers?

But when I do this I notice that the addresses do not follow each other :

  int arrays[3] = {10, 20, 30};
  int i = 0;

  for (i=0 ; i < 3 ; i  )
  {
    printf("%d : %d\n", i, &arrays[i]);
  }

Result : 0 : 973077712 1 : 973077716 2 : 973077720


And when I do this I notice that array and &array give me the same value which should not be the case for a "classic pointer" :

  printf("value of arrays : %d\n", arrays);
  printf("value of &arrays : %d\n", &arrays);

Result : value of arrays : 1522530048 value of &arrays : 1522530048

CodePudding user response:

If you have an array of some type T like

T a[N];

then the difference between the addresses of two adjacent elements of the array are equal to sizeof( T ). And this output shows that convention provided that in your system sizeof( int ) is equal to 4.

Result : 0 : 973077712 1 : 973077716 2 : 973077720

That is as pointed out above sizeof( int ) in the used system is equal to 4. So for example the difference between the addresses of the first and the second element is equal to

 973077716
-
 973077712
 =========
 000000004 

The address of an array is the address of the extent of memory occupied by the array. And obviously it is the address of the first element of the array. So values of the expressions

&array[0]

and

&array

are the same. But expressions themselves have different types. The first expression has the type int * while the second expression has the type int ( * )[3].

Pay attention that using the conversion specifier d with pointers in calls of printf is incorrect. For example instead of these records

  printf("value of arrays : %d\n", arrays);
  printf("value of &arrays : %d\n", &arrays);

you have to write

  printf("value of arrays : %p\n", ( void * )arrays);
  printf("value of &arrays : %p\n", ( void * )&arrays);

Arrays used in expressions with rare exceptions are converted to pointers to their first elements.

From the C Standard (6.3.2.1 Lvalues, arrays, and function designators)

3 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.

CodePudding user response:

two things that cause me problems :

  • The first is that in the RAM each of the boxes that make up the table follows one another

This is true, supposing that by "table" you mean "array".

  • The second is that a table is a pointer that points to the first box of the table

This is false, and manifestly incompatible with the previous statement.

However, in most places where an array's name or some other array-valued expression is evaluated, the (array) result is automatically converted to a pointer to the first element of the array.


when I do this I notice that the addresses do not follow each other :

  int arrays[3] = {10, 20, 30};
  int i = 0;

  for (i=0 ; i < 3 ; i  )
  {
    printf("%d : %d\n", i, &arrays[i]);
  }

Result : 0 : 973077712 1 : 973077716 2 : 973077720

Formally, that tells you nothing, because its behavior is undefined. The correct printf formatting directive for pointers is %p, not %d, and technically, it is appropriate only for pointers to void. The mismatch between the format directive and the data type of the corresponding argument produces UB. Instead, you want this:

    printf("%d : %p\n", i, (void *) &arrays[i]);

However, you will likely find that the (hexadecimal) results still are not sequential numbers. That would be because objects of type int require more than one unit of storage each. The difference between the addresses of consecutive int units in your array is the size in bytes of one int.


And when I do this I notice that array and &array give me the same value which should not be the case for a "classic pointer" :

  printf("value of arrays : %d\n", arrays);
  printf("value of &arrays : %d\n", &arrays);

Result : value of arrays : 1522530048 value of &arrays : 1522530048

Again, undefined behavior. But you would see similar from the correct code. This is because of the automatic conversion of arrays to pointers that I described above, and from the fact that one of the few exceptions to that behavior is when an array-valued expression is the operand of the address-of (unary &) operator. Thus arrays is automatically converted to a pointer to the first array element, and &arrays evaluates to a pointer to the whole array. These have different (pointer) types, but the address of the first element is the same as the address of the whole array.

  • Related