Doesn't & mean "memory address of" x in C++?
Short answer: That depends.
Somewhat longer answer:
The unary prefix operator &, when applied to an object, indeed yields the address of the object: &obj. There is, however, also the type modifier &, which, when applied to a type, will modify it to be a reference: int&.
The same applies to *: When used as a unary prefix operator, it will dereference a pointer: *ptr. When used as a type modifier, it will modify the type to be a pointer: int*.
It's not helpful either that the type modifiers apply to the variable that is declared. For example, this
int *p, **pp, i, &r = i;
defines an int pointer, a pointer to a pointer to an int, a vanilla int, and an int reference. (The latter is immediately initialized, because you cannot have an uninitialized reference.) Note that the modifiers syntactically belong to the declared variable whose type they are modifying, not to the type of the declared variable. Nevertheless, in this example the * and & modify the type of the variable.
In the following case, however, with p and i presumed to be variables
*pp = &i;
* and & are unary prefix operators dereferencing pp and yielding the address of i.
To complicate things even further, besides the type modifiers and the unary prefix operators & and *, there are also the binary infix operators & and *, meaning "bitwise AND" and "multiplication". And to add insult to injury, in C++ you can overload both the unary prefix and the binary infix variants of the operator for user-defined types and be completely free as to their meaning.