c++ pointer declaration and assignment [duplicate] - c++

This question already has answers here:
What are the barriers to understanding pointers and what can be done to overcome them? [closed]
(28 answers)
Closed 8 years ago.
int num1 = 8; //okay
int *pointer; //okay
*pointer = &num1; //NOT okay, compiler says (Error:a value of type int* cannot be
//assigned to an entity of type "int")
int num2 = 8; //okay
int *pointer = &num2; //okay
I am confused why the first part gives an error and the 2nd part doesnt, they look the same to me

In the assignment statement:
*pointer = &num1; //NOT okay
*pointer is the value that pointer points to, of type int, and &num1 is the address of num1, of type int*. As the compiler says, you can't assign a pointer to an integer.
pointer = &num1 or *pointer = num1 would both be fine, depending on whether you want to modify the pointer itself, or the value it points to.
In the declaration:
int *pointer = &num2; //okay
Despite the similar appearance to the assignment statement, this initialises pointer not *pointer. It declares pointer to be a pointer, of the same type int* as &num2.

Remove the * in third line. It returns the value stored at position/address currently stored in variable pointer and interprets it as int.

The operator & gives a pointer to the variable over which is acting.
&num1 is a pointer to int (since num1 has type int) which points to the address of num1.

The error message is very clear: The expression *pointer is of type int and the expression &num1 is of type int*. Those two types are not compatible (you try to assign a pointer to a non-pointer).
When you use the dereference operator * on a pointer, you get what the pointer is pointing to, and if you use the address-of operator & you get the address of (i.e. pointer to) something.
To make pointer point to a variable, then just assign to it:
pointer = &num1;

int *pointer = &num2;
is the same as
int *pointer;
pointer = &num2;
not
int *pointer;
*pointer = &num2;

The following is more of a general description rather than a direct answer to your question...
If you declare a variable of some type, then you can also declare another variable pointing to it.
For example:
int a;
int* b = &a;
There are two ways to "look at" variable b (that's what probably confuses most beginners):
You can consider b as a variable of type int*.
You can consider *b as a variable of type int.
Hence, some programmers would declare int* b, whereas others would declare int *b.
But the fact of the matter is that these two declarations are identical (the spaces are meaningless).
You can use either b as a pointer to an integer value, or *b as the actual pointed integer value.
You can read the pointed value (e.g., int c = *b) and write the pointed value (e.g., *b = 5).

Related

Why can't I directly assign an int to an int pointer like this: int *p = 6;?

error: invalid conversion from 'int' to 'int*'
int *q = 8;
Works fine.
*q = 6;
Why can't I directly assign an int to an int pointer like this: int *q = 6; and I can assign it safely in the next line?
Because they're different things at all. The 1st one is definition of variable with initializer expression, i.e an initialization (of the pointer itself):
int * q = 8;
~~~~~ ~ ~~~
type is int*; name of variable is q; initialized with 8
The 2nd one is assignment (of the object pointed by the pointer):
*q = 6;
~~ ~~~
dereference on q via operator*; assign the resulting lvalue pointed by q to 6
And, int *p = 6; means define a variable named p with type int* and initialize it with 6, which fails because 6 can't be used for initializing a pointer directly (i.e. the error "invalid conversion from 'int' to 'int*'").
* symbol is reused for two different purpuses in your snippet. First time it is used as a part of type declaration int *, declaring a pointer to int. Second time it is used to dereference a pointer *q, invoking indirection operator.
* can also be used to invoke multiplication operator *q = *q * *q;;
To assign a value to an integer pointed by pointer you need to dereference it. And to assigning integral value other than 0 to a pointer itself (that is what int *q = 8; is doing) requires reinterpret_cast, hence you get this error.
Statement int *q defines a variable of type "pointer to integer", and an initialisation therefore needs to be a pointer value, not an integral value.
So int *q = 8 is not the same as int *q; *q = 8 (which would be undefined behaviour because it dereferences an uninitialized pointer), but more like int *q; q = 8, which makes the misunderstanding more transparent.
This:
int *q = 8;
is an initialization. It initializes q (the pointer), not *q (what it points to). Writing this equivalently with an assignment instead of initialization would look like:
int *q;
q = 8;
So you see it doesn't make sense. (and, isn't allowed of course -- an int is not a pointer)
Just to be sure, if you write:
int *q;
*q = 8;
this is syntactically correct, but undefined behavior. Your pointer doesn't point to an object of type int, it is uninitialized and probably pointing to some invalid location. Writing there, anything could happen.
Because the types don't match.
The 6 itself is not a value of pointer type, it's an integer so it cannot be directly stored in a pointer.
When you do *q = 6 the * dereferences the pointer, so the type becomes int (or rather an lvalue int, i.e. something that can be assigned to).
Here, assign the value 8 to an object of type int*. It means q points on address 8 on memory.
int *q = 8;
Is equivalent to:
int *q;
q = 8;
Is Not equivalent to:
int *q;
*q = 8;
is illegal, as it involves constraint violation.
Related stack overflow question: Is it possible to initialize a C pointer to NULL?
A pointer variable holds an address, or 'location' of something. Thus, the pointer holds a value that is a memory address. When you say:
int *q = 6;
you are creating a pointer variable that intends to point to an int, and telling it to point to the int value stored in the address 6, which is (probably) not what you really intended.
A pointer variable should point to some memory address that contains some actual data you want to access. For example:
int x = 5;
int *q = &x;
This creates a variable (x) that contains the value 5.
the next line creates a pointer variable that contains the address of x. You have set the pointer variable 'q' to the address of the int variable 'x'.
Now you can see what is at 'x' by doing this:
int y;
y = *q;
This says "take what is pointed to by q, and store it in y". The end effect is that y will be set to 5.
int x = 5; // create variable x and set it to 5
int *q = &x; // create int pointer variable, set it to the address of x
int y; // create variable y
y = *q; // take the value pointed to by q, and store it in y
If, for example the variable x is at memory location 1234, and you looked at the value stored in 'q', it would be 1234, which is the address of x.
When you say "y = *q", you are saying "take the value stored in the address 1234, and puts that value in y". Since the memory location 1234 is 'x', and 'x' was assigned the value 5, the value 5 will be what is stored at the address 1234.
y = *q;
will take the value stored in the address 1234 and assign y to that value, thus making y 5, which was the value stored in x, which is what q 'points' to.
This could be shortened to:
int x = 5;
int *q = &x;
int y = *q;
When you write
int *q = 8; it means you declared a pointer q and initialized a pointer with the integer 8. but q being a pointer expects a address value therefore you get error stating incompatibility.
Whereas when you write
*q=8 after declaring, it means you are dereferencing the addresses pointed by q and writing a value to that location. here q points to a int so you are writing 8 a integer value to the location pointed by q. that is right. This can also lead to error at runtime if q is not initialized to point to right location.
In your first statement you are declaring and initializing the pointer to some value of type int (on the same line). In your second statement you are changing the value pointed to by a pointer. Two different things. What you have there is initialization followed by an assignment. Don't let the * confuse you.
Because it is not valid C, simple as that. Specifically, it is a constraint violation of the assignment operator, since integer to pointer or pointer to integer is not valid forms of "simple assignment" (C11 6.5.16.1).
You can convert between integers and pointers by adding an explicit cast. The result is however not guaranteed to work: pointers and integers may have different representations and there might be alignment issues.
In case of *q = 6; you assign an int to an int, which is of course perfectly fine (given that the pointer points at allocated memory somewhere).
If you re-write it like this:
int* q = 8;
*q = 6;
Then you can see the * has two different purposes.
Try
int *q = new int(8);
But working with pointers here is not normally required. If you have to use pointer, use smart pointer shared_ptr<int> or uniqe_ptr<int>.
In this case you are assigning value 8 to pointer *q and it wont work during initialization, Memory address is unique at that time not available to assign but you can set once memory block created after initialization for *q.

What exactly is the purpose of the (asterisk) in pointers?

I'm new to programming and I'm trying to wrap my head around the idea of 'pointers'.
int main()
{
int x = 5;
int *pointerToInteger = & x;
cout<<pointerToInteger;
}
Why is it that when I cout << pointerToInteger; the output is a hexdecimal value, BUT when I use cout << *pointerToInteger; the output is 5 ( x=5).
* has different meaning depending on the context.
Declaration of a pointer
int* ap; // It defines ap to be a pointer to an int.
void foo(int* p); // Declares function foo.
// foo expects a pointer to an int as an argument.
Dereference a pointer in an expression.
int i = 0;
int* ap = &i; // ap points to i
*ap = 10; // Indirectly sets the value of i to 10
A multiplication operator.
int i = 10*20; // Needs no explanation.
One way to look at it, is that the variable in your source/code, say
int a=0;
Makes the 'int a' refer to a value in memory, 0. If we make a new variable, this time a (potentially smaller) "int pointer", int *, and have it point to the &a (address of a)
int*p_a=&a; //(`p_a` meaning pointer to `a` see Hungarian notation)
Hungarian notation wiki
we get p_a that points to what the value &a is. Your talking about what is at the address of a now tho, and the *p_a is a pointer to whatever is at the &a (address of a).
This has uses when you want to modify a value in memory, without creating a duplicate container.
p_a itself has a footprint in memory however (potentially smaller than a itself) and when you cout<<p_a<<endl; you will write whatever the pointer address is, not whats there. *p_a however will be &a.
p_a is normally smaller than a itself, since its just a pointer to memory and not the value itself. Does that make sense? A vector of pointers will be easier to manage than a vector of values, but they will do the same thing in many regards.
If you declare a variable of some type, then you can also declare another variable pointing to it.
For example:
int a;
int* b = &a;
So in essence, for each basic type, we also have a corresponding pointer type.
For example: short and short*.
There are two ways to "look at" variable b (that's what probably confuses most beginners):
You can consider b as a variable of type int*.
You can consider *b as a variable of type int.
Hence, some people would declare int* b, whereas others would declare int *b.
But the fact of the matter is that these two declarations are identical (the spaces are meaningless).
You can use either b as a pointer to an integer value, or *b as the actual pointed integer value.
You can get (read) the pointed value: int c = *b.
And you can set (write) the pointed value: *b = 5.
A pointer can point to any memory address, and not only to the address of some variable that you have previously declared. However, you must be careful when using pointers in order to get or set the value located at the pointed memory address.
For example:
int* a = (int*)0x8000000;
Here, we have variable a pointing to memory address 0x8000000.
If this memory address is not mapped within the memory space of your program, then any read or write operation using *a will most likely cause your program to crash, due to a memory access violation.
You can safely change the value of a, but you should be very careful changing the value of *a.
yes the asterisk * have different meanings while declaring a pointer variable and while accessing data through pointer variable. for e.g
int input = 7;
int *i_ptr = &input;/*Here * indicates that i_ptr is a pointer variable
Also address is assigned to i_ptr, not to *iptr*/
cout<<*i_ptr;/* now this * is fetch the data from assigned address */
cout<<i_ptr;/*it prints address */
for e.g if you declare like int *ptr = 7; its wrong(not an error) as pointers ptr expects valid address but you provided constant(7). upto declaration it's okay but when you go for dereferencing it like *ptr it gives problem because it doesn't know what is that data/value at 7 location. So Its always advisable to assign pointers variable with valid addresses. for e.g
int input = 7;
int *i_ptr = &input;
cout<<*i_ptr;
for example
char *ptr = "Hello"; => here * is just to inform the compiler that ptr is a pointer variable not normal one &
Hello is a char array i.e valid address, so this syntax is okay. Now you can do
if(*ptr == 'H') {
/*....*/
}
else {
/*.... */
}

When should I use * and when &? [duplicate]

This question already has answers here:
When to use references vs. pointers
(17 answers)
Closed 7 years ago.
I am learning some C++, and I came across pointers and addresses. However, in none of the materials, I could find a good explanation on when to use pointer, and when to use address. As I understand it is that when I use pointer, I POINT to address in memory, where some variable is stored. So for example:
int x = 5;
int k* = &x;
Which will mean that:
k represents x
When I change k, I also change value of x.
My question is as follows: when should I use pointer, and when should I use address? When I declare a function, should I use pointer, or address as a variable?
You have a typo there. It should be:
int x = 5;
int *k = &x;
It should be read as: k points to x. Or if you insist on the "represent" word: *k represents x.
The & operator takes any variable as argument and returns its address (pointer). The * gets a pointer (address) as argument and returns the value stored there. As such they are opposite operations: &*k is the same as k and likewise *&x is just like x. You can look at these expression this way:
x //an integer
k //pointer to integer
&x //pointer to x
*k //integer pointed to by k
*&x //integer pointed to by a pointer to x, that is x
&*k //pointer to the integer pointed to by k, that is k
Note that operator & can only be used on variables, as expressions in general do not have addresses, only variables do (well, and temporaries, but that is another matter). For example, this expression is invalid:
&(x + 1) //error!
The funniest thing with these operator is how a pointer is declared:
int *k;
You might think that it would be better written as int &k, but that's not how declarators are read in C++. Instead, that declaration should be read as:
int (*k);
that is, *k is an integer, so it results that k is a pointer to an integer.
Now, the declaration with initialization is weirder:
int *k = &x;
should actually be read as:
int (*k);
k = &x;
That is, you declare *k as being an integer, thus, k is a pointer-to-integer. And then you initialize k (the pointer) with the address of x.
Actually you can create pointers of any type, even pointers to pointers, pointers to pointers to pointers... but note that this syntax is illegal:
int x;
int **p = &&x; //error, &x is not a variable
but this is valid:
int x;
int *k = &x;
int **p = &k;
If a variable stores an address of a memory location, it is considered a pointer. So an int * for example stores the address of an int-variable. By using the dereference-operator *, you can access the memory location at the address of the pointer and assign to it.
To get the address of a variable, you use the &-operator. This is what your example does. To assign to the memory-location where x is stored, you would use the derefence-operator again like this: *k = 0;
Note that the derefence-operator and the * to express a pointer type are two different things. * and & are each other's inverse (overloading aside) operators, while int * is a type.
In C++ in particular, if the & is used together with a type, the type of the variable is a reference-type, e.g. const string &s. Just like the pointer-type this is different from the address-of operator. Reference-types do not need to be derefenced using *, but will direcly modify the memory location they reference.
Pointer operator (*) is used whenever you want to point to a variable.
Address operator (&) is used whenever you point to the memory address of a variable.

assigning an address to a pointer

I wanted to know if there are alternative ways of assigning a pointer the address of the value its pointing to. For example, there's the usual way:
int a = 10;
int *ptr;
ptr = &a;
but at some places I see it declared like:
int *ptr = &a;
Are both of these ways equivalent? I am slightly confused because I always considered *ptr as giving the value of a, and not the address. Could anyone please explain? Thanks.
I am slightly confused because I always considered *ptr as giving the value of a, and not the address.
It is indeed a bit confusing as * is used to declare a pointer, and also used as the dereference operator. The actual meaning of * depends on the context - whether is used in a declaration, an initialisation or an assignment.
It's worth knowing the differences between 1) declaration, 2) initialisation, and 3) assignment.
int *ptr; // 1) this is declaration without initialisation.
int *ptr = &a; // 2) this is declaration **and** initialisation (initialise ptr to the address of variable a)
int b = 10;
*ptr = b; // 3) this is assignment, assign what pointed by ptr to value of variable b.
In 1) the * means that ptr is a pointer to int (but it has not pointed to any valid location yet).
In 2) the * means that ptr is a pointer to int, and its initial value is the address of variable a.
In 3) the * is the dereference operator, ie assigning what pointed by ptr to the value of variable b.
int *ptr; ptr = &a; is to int *ptr = &a; as int n; n = 3; is to int n = 3;.
That is, pointer declaration and initialisation is no different to normal variables. I prefer to use one line whenever possible since then there is less danger of having uninitialised variables.
No ..it is declaration and intiliaziation in one line.
This will clear the idea..
typedef int* intp;
intp ptr=&a;
Equivalently
intp ptr; //int *ptr;
ptr=&a; // ptr=&a;
Answer is : YES they are equivalent.
You may ask-
:- How do a compiler understand?(whether * is indirection or as in declaration)
Ans:- C is context sensitive..based on the context on which it is used compiler decides it.
Are both of these ways equivalent?
Yes.
The second one is marginally preferred as the first one leaves ptr unassigned until the last line (though in practise a compiler would probably optimise that out).
I am slightly confused because I always considered *ptr as giving the value of a, and not the address.
You are confusing the syntax declaring a variable with the syntax for using that variable.
int *ptr;
just declares a variable called ptr that is a pointer to an integer.
int *ptr = &a;
does exactly the same. The first part is still just the declaration of the pointer as before. The part after the equals sign initialises ptr to the address of a
You are correct that after declaration when you later use this variable in subsequent code specifying *ptr will give you the contents of the pointer (in this case the value of a).
If * operator is used at the time of declaration then it's just used to indicate the type of variable being declared. Whereas in all other cases * operator is used as dereference operator (except where it's used as multiplication operator).
So int *ptr = &a means ptr is a variable of type int * which has been assigned &a
And *ptr = a means variable stored at address ptr (dereferencing ptr) which is being assigned a.

reassign pointer gives error

I am new to C++ , therefore please forgive me if my question seems basic, I am not able to reassign a pointer when I use the star, here is my code:
int val = 8;
int number = 23;
int *pointer = &val;
*pointer = &number; //<-- error
this gives an error: assign to int from incompatible type int. here is what I tried:
pointer = &number; // this works
therefore my question is, why is this wrong: *pointer = &number
In your code,
*pointer = &number; //<-- error
by saying *pointer, you're dereferencing the pointer, which is of type int, then you try to assign a pointer type value to it, which is not correct.
What you want to do, is to assign the address of a variable and to hold that, you want the pointer variable itself to be on the LHS of the assignment. So,
pointer = &number;
is the correct way to go.
The reason this results in an error is because you misunderstood the type of each variable.
int val = 8; // type of `val` is int
int number = 23; // type of `number` is an int
int *pointer = &val; // type of `pointer` is an int *
*pointer = &number; // type of `pointer` is int *, so type of `*pointer` is int
It doesn't work because *pointer dereferences the pointer, so you're assigning an address to a pointer, which is not what you want.
When you say
int *pointer
the * indicates that you are creating a pointer, you can think of the * as part of the data type. i.e. it's a pointer to an integer type. To reference the pointer itself (the type that stores an address in memory), you simply use the name of the pointer, just like a regular variable.
When you add the * infront, you are dereferencing the pointer. Meaning, you are accessing whatever is stored at the memory address that the pointer is pointing to, in this case an int.
Basically, pointer gives you an address in memory, *pointer gives you the int stored at that address.
int *pointer = &val;
Breaking this up actually means
int* pointer;
pointer = &val;
When you derefrence an integer pointer it becomes just an integer.When you add & to a non-pointer it becomes a pointer.So doing
is bad,because *ptr is not a pointer and &i is a pointer
int n = 0;
int *ptr = &n //good,because they are both pointers
int i = 0;
*ptr = &i //bad because only one is a pointer