Reputation: 31
I thought a[]
and *a
are the same thing because they work like pointers. Yet I encountered something unexpected in the following code:
#include <iostream>
using namespace std;
class F {
public:
bool a[];
F();
};
F::F() {
*a = new bool[5];
a[2] = true;
}
int main() {
F obj;
if(obj.a[2])
cout << '?';
return 0;
}
This code prints ?
, but I don't understand how it works. When:
*a = new bool[5];
is changed into:
a = new bool[5];
compiler reports:
F:\main.cpp|11|error: incompatible types in assignment of 'bool*' to 'bool [0]'|
I found this behaviour weird, so I was playing around with this code. When I changed the type of a
from bool
to int
compiler always reports an error
F:\main.cpp|11|error: invalid conversion from 'int*' to 'int' [-fpermissive]|
Why does this work the way it does?
Upvotes: 2
Views: 119
Reputation: 363
Type of value returned from new Type[x]
is Type *
i.e pointer of that type
examle:
So Right syntax is
bool a;
*a = new bool[x];
so it is wrong to do like is
a=new bool[x]
wrong syntax as it is invalid to assign pointer to a normal varibale
Upvotes: 0
Reputation: 72226
I thought
a[]
and*a
are the same thing because they work like pointers.
Let's talk about this piece of declaration:
int a[4] = { 1, 2, 3, 5 };
int *b = NULL;
This is how they land in memory in the executable:
+----+----+----+----+
a: | 1 | 2 | 3 | 5 | <-- 4 integers
+----+----+----+----+
+----------+
b: | NULL | <-- 1 pointer that points to nowhere
+----------+
As you can see, they are not the same thing.
What happens after b = new int[4];
?
The new memory layout of b
is something like this:
+----------+
b: | 0xacf3de | <-- 1 pointer that points to a block of 4 integers
+----------+
Somewhere else in memory (at address 0xacf3de)...
+----+----+----+----+
0xacf3de: | ? | ? | ? | ? | <-- 4 integers
+----+----+----+----+
But wait, somebody told me that arrays work like pointers...
No, that's not true. The arrays do not work like pointers.
An array name (a
, f.e.) can be used as a shortcut for its address in memory (which is, in fact, the address of its first element). The following notations are equivalent:
a
&a
&a[0]
The value of all of them is the address in memory where the first element of a
(the 1
in the example above) is stored.
a[0]
is an int
, &a[0]
is an int *
. This is the complete form. The other two are shortcuts that the language provides in order to make the code easier to read and understand.
The things are different for pointers.
b
is the value stored in the b
variable (NULL
or 0xacf3de
in the example above. It is a value of type int *
-- the address in memory where an int
is stored. &b
is the address in memory where (the value of) b
is stored. Its type is int **
-- a pointer to a pointer to an int
; or "the address in memory where is stored the address of an int
".
But wait, they can be replaced one for another in some contexts
Up to some point, yes, a pointer and an array are interchangeable. As you can see above, there is a common data type involved: int *
. It is the type of b
(which stores the address of an int
) and also the type of &a[0]
(which is also the address of an int
).
This means that where b
can be used, a
(a short of &a[0]
) can be used instead, and vice-versa.
Also, where *b
can be used, *a
can be used instead. It is the short for *&a[0]
and it means "the value (*
) stored at the address (&
) of a[0]
" and it is, in fact, the same as a[0]
.
But, where &b
can be used, &a
cannot be used instead; remember that &a
is the same as &a[0]
and its type is int *
(but the type of &b
is int **
).
Upvotes: 2
Reputation: 15976
The line:
*a = new bool[5];
is equivalent to:
a[0] = new bool[5];
You are not initialiazing your array, but allocating an array of bool
which is then implicitly converted into bool
to be assigned to a[0]
: the value should be true
since the pointer returned by new
should be different from 0
. This implicit conversion does not apply with int
s: that is why you are getting an error when changing the type of a
.
Now, considering this line:
a = new bool[5];
Here you are trying to assign your dynamically allocated array to a
, in other words assigning a pointer to an array bool*
to a static array bool[0]
: as the compiler says, the types are incompatible. A static array a[]
can be used as a pointer, e.g. in the following code:
int foo(bool* a) { /* ... */ }
bool my_array[5];
foo(my_array);
But pointers can not be converted into static arrays as you are trying to do.
Upvotes: 2