Reputation: 5012
Does
int **p
and
int *p[1]
mean the same thing? as both can be passed to functions allowing the change the pointer object, also both can be accessed via p[0], *p ?
Update, thanks for your help, tough Memory management seems different. does the access mechanism remain the same
*eg: p[0] becomes *(p+0) & *p (both pointing to something)
Thanks
Upvotes: 2
Views: 549
Reputation: 67822
Not quite.
int **p;
declares a pointer p
, which will be used to point at objects of type int *
, ie, pointers to int. It doesn't allocate any storage, or point p
at anything in particular yet.
int *p[1];
declares an array p
of one pointer to int: p
's type can decay to int **
when it's passed around, but unlike the first statement, p
here has an initial value and some storage is set aside.
Re. the edited question on access syntax: yes, *p == p[0] == *(p+0)
for all pointers and arrays.
Re. the comment asking about sizeof
: it deals properly with arrays where it can see the declaration, so it gives the total storage size.
void foo()
{
int **ptr;
int *array[10];
sizeof(ptr); // just the size of the pointer
sizeof(array); // 10 * sizeof(int *)
// popular idiom for getting count of elements in array:
sizeof(array)/sizeof(array[0]);
}
// this would always discard the array size,
// because the argument always decays to a pointer
size_t my_sizeof(int *p) { return sizeof(p); }
Upvotes: 7
Reputation: 123578
They are not the same thing, although in many cases they can appear to behave the same way.
To make the discussion below flow better, I'm going to take the liberty of renaming your variables:
int **pp; // pointer to pointer
int *ap[1]; // array of pointer
If an expression of type "N-element array of T
" appears in most contexts, it will be converted to an expression of type "pointer to T
" whose value is the address of the first element in the array (the exceptions to this rule are when the array expression is an operand of either the sizeof
or unary &
operators, or is a string literal being used to initialize another array in a declaration).
So, suppose you write something like
foo(ap);
The expression ap
has type "1-element array of pointer to int
", but by the rule above it will be converted to an expression of type "pointer to pointer to int
"; thus, the function foo
will receive an argument of type int **
, not int *[1]
.
On the other side of the equation, subscripting is defined in terms of pointer arithmetic: E1[E2]
is defined as *(E1 + E2)
where one of the expressions is a pointer value and the other is an integral value. Thus you can use a subscript operator on pp
as though it were an array. This is why we can treat dynamically-allocated buffers as though they were regular arrays:
pp = malloc(sizeof *pp * N); // allocate N pointers to int (type of *pp == int *)
if (pp)
{
size_t i;
for (i = 0; i < N; i++)
pp[i] = ...; // set pp[i] to point to some int value
}
Now for some major differences. First of all, array expressions may not be the target of an assignment; for example, you can't write something like
ap = some_new_pointer_value();
As mentioned above, array expressions will not be converted to pointer types if they are the operands of either the sizeof
or unary &
operators. Thus, sizeof ap
tells you the number of bytes required to store a 1-element array of type int *
, not a pointer to a pointer to int
. Similarly, the expression &ap
has type int *(*)[1]
(pointer to 1-element array of pointer to int
), rather than int ***
(which would be the case for &pp
).
Upvotes: 2
Reputation: 500893
To simplify things, you could factor out one level of pointers since it's not relevant to the question.
The question then becomes: what's the difference between T* t
and T t[1]
, where T
is some type.
There are several differences, but the most obvious one has to do with memory management: the latter allocates memory for a single value of type T
, whereas the the former does not (but it does allocate memory for the pointer).
Upvotes: 4
Reputation: 60711
They are different.
int **p
means a pointer to a pointer to an int.
int *p[1]
means an array containing one element, with that element being a pointer to an int.
The second form can be treated the same as the first in some situations, e.g. by passing it to a function.
Upvotes: 1
Reputation: 206636
They are not same:
int **p
Is a pointer which points to another pointer whose type is int *
while,
int *p[1];
Is an array of size 1
to the type int *
Upvotes: 1
Reputation: 272762
No, they are not the same.
int **p
is a pointer to a pointer to int
.int *p[1]
is an array (of length 1) of pointers to int
.Upvotes: 1