polymorph
polymorph

Reputation: 79

Array Pointers vs Regular Pointers in C

I am a total beginner to C so please, work with my ignorance. Why does a normal pointer

int* ptr = &a; has two spaces in memory (one for the pointer variable and one for the value it points to) and an array pointer int a[] = {5}; only has one memory space (if I print out

printf("\n%p\n", a) I get the same address as if I printed out: printf("\n%p\n", &a).

The question is, shouldn't there be a memory space for the pointer variable a and one for its value which points to the first array element? It does it with the regular pointer int* ptr = &a;

Upvotes: 0

Views: 156

Answers (6)

mblw
mblw

Reputation: 1798

The main misunderstanding here is that &a return not pointer to pointer as it expected that's because in C language there some difference between [] and * (Explanation here: Difference between [] and *) If you try to &a if a was an pointer (e.g. int *a) then you obtain a new memory place but when your use a static array (i.e. int a[]) then it return address of the first array element. I'll also try to clarify this by mean of the next code block.

#include <stdio.h>

int main(int argc, char *argv[])
{
    // for cycles
    int k; 

    printf("That is a pointer case:\n");
    // Allocate memory for 4 bytes (one int is four bytes on x86 platform, 
    // can be differ for microcontroller e.g.)
    int c = 0xDEADBEEF;
    unsigned char *b = (unsigned char*) &c;
    printf("Value c: %p\n", c);
    printf("Pointer to c: %p\n", &c);
    printf("Pointer b (eq. to c): %p\n", b);
    // Reverse order (little-endian in case of x86)
    for (k = 0; k < 4; k++)
        printf("b[%d] = 0x%02X\n", k, b[k]);

    // MAIN DIFFERENCE HERE: (see below)    
    unsigned char **p_b = &b;
    // And now if we use & one more we obtain pointer to the pointer
    // 0xDEADBEEF <-- b <-- &p_b
    // This pointer different then b itself
    printf("Pointer to the pointer b: %p\n", p_b);

    printf("\nOther case, now we use array that defined by []:\n");
    int a[] = {5,1};
    int *ptr = &a;
    // 'a' is array but physically it also pointer to location
    // logically it's treat differ other then real pointer
    printf("'a' is array: %x\n", a);
    // MAIN DIFFERENCE HERE: we obtain not a pointer to pointer
    printf("Pointer to 'a' result also 'a'%x\n", &a);
    printf("Same as 'a': %x\n", ptr);
    printf("Access to memory that 'a' pointes to: \n%x\n", *a);

    return 0;
}

Upvotes: 1

Tarik
Tarik

Reputation: 11209

ptr is a variable containing a memory address. You can assign various memory addresses to ptr. a is a constant representing a fixed memory address of the first element of the array. As such you can do:

ptr = a;

but not

a = ptr;

Upvotes: 0

Tony The Lion
Tony The Lion

Reputation: 63200

In this expression, int* p = &a; p has only one memory location, of the WORD size of your CPU, most probably, and it is to store the address (memory location) of another variable.

When you do *p you are dereferencing p, which means you are getting the value of what p points to. In this particular case that would be the value of a. a has its own location in memory, and p only points to it, but does not itself store as content.

When you have an array, like int a[] = {5};, you have a series (or one) of memory locations, and they are filled with values. These are actual locations.

Arrays in C can decay to a pointer, so when you printf like you did with your array, you get the same address, whether you do a or &a. This is because of array to pointer decay.

a is still the same location, and is only that location. &a actually returns a pointer to a, but that pointer sits else where in memory. If you did int* b = &a; then b here would not have the same location as a, however, it would point to a.

Upvotes: 0

pmg
pmg

Reputation: 108988

Pointers point to an area in memory. Pointers to int point to an area large enough to hold a value of int type.

If you have an array of int and make a pointer point to the array first element

int array[42];
int *p = array;

the pointer still points to a space wide enough for an int.

On the other hand, if you make a different pointer point to the whole array, this new pointer points to a larger area that starts at the same address

 int (*q)[42]; // q is a pointer to an array of 42 ints
 q = &array;

the address of both p and q is the same, but they point to differently sized areas.

Upvotes: -1

0xF1
0xF1

Reputation: 6116

This is very simple. In first case,

int* ptr = &a;

you have one variable a already declared and hence present in memory. Now you declare another variable ptr (to hold the address, in C variables which hold address of another variable are called pointers), which again requires memory in the same way as a required.

In second case,

int a[] = {5};

You just declare one variable (which will hold a collection of ints), hence memory is allocated accordingly for a[].

Upvotes: 0

duncan
duncan

Reputation: 456

It's a little unclear from your question (and assuming no compiler optimization), but if you first declare a variable and then a pointer to that variable,

int a = 4;
int *p = &a;

then you have two different variables, it makes sense that there are two memory slots. You might change p to point to something else, and still want to refer to a later

int a = 4;
int b = 5;

int *p = &a; // p points to a

// ...

p = &b; // now p points to b
a = 6; // but you can still use a

The array declaration just allocates memory on the stack. If you wanted to do the same with a pointer, on the heap, you would use something like malloc or calloc (or new in c++)

int *p = (int*)malloc(1 * sizeof(int));
*p = 4;

but of course remember to free it later (delete in c++)

free(p);
p = 0;

Upvotes: 2

Related Questions