Reputation: 79
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
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
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
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 a
s 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
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
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
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