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
Related
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.
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).
General syntax of pointer declaration: data-type *pointer_name;
A pointer is a variable whose value is the address of another variable, i.e., direct address of the memory location. Like any variable or constant, you must declare a pointer before you can use it to store any variable address. The data type of pointer must be same as the variable, which the pointer is pointing.
Why is it important that a pointer variable should contain the address of a variable of the same data type?
As a pointer has nothing to do with the value of another variable, why can't an integer pointer have the address of float data type variable?
Correct form:
int a = 10 ;
int *ptr = &a ;
ERROR, type mismatch
float a;
int *ptr; ptr = &a;
Because when you increase a pointer like
ptr++;
it will point to an address that is one multiplied with the size of the data type. If you do
ptr+=2;
and the data type is occupying 4 bytes which would be the case if the pointer was declared as
float *ptr;
the pointer will increase with 8 byte positions.
Before answering that, let me ask you, if it were valid, what would you do with such a pointer?
Suppose you have (inside a function)
float a;
int *ptr; ptr = &a;
*p = 1;
++*p;
return *p;
In such a case, there is no reason at all not to just use an int variable if it's an int you want.
Suppose you have (inside a function)
float a;
int *ptr; ptr = &a;
a = 3.14;
++*p;
return a;
In this sort of object aliasing, there can be a use, but allowing constructions like this is a pain for compilers. Compilers are free to assume, and some do assume, that the modification of *p has no effect on the value of a, so still return 3.14 unmodified;
If the latter case is something you're looking for, you can use union, which both makes your code clearer to other readers, and makes your code clearer to the compiler:
union {
float f;
int i;
} u;
u.f = 3.14;
++u.i;
return u.f;
So, to answer: it's to prevent you from shooting yourself in the foot. It's not allowed because there is no way such a pointer is useful. The one case where it could be useful is actually a case where it doesn't work, and there is another language construct that does handle it, and handles it correctly.
There is also the simple matter of dereferencing the pointer.
something = *pointer;
How much data should be read when the pointer is dereferenced? The compiler must know the data type in order to perform operations on the data like fetch, add, etc.
It's a safety feature. A pointer of one type pointing to a variable of another is a recipe for disaster; it has almost no legitimate purpose and almost anything you do with it is dangerous, especially if the types are of different sizes.
You can override this feature by means of casting. If you do so, you can no longer claim that you didn't know you were doing something dangerous.
It is possible for pointers to point to any data type: that's exactly what void pointers are for. You can use a void * to point to any data type1, and then you can get the original pointer back.
float f = 1.0f;
int i = 12;
void *p = &f;
p = &i;
Of course, you can't dereference a void pointer without first casting it back to the correct pointer type. It is up to you to ensure that the pointer type is correct.
// In C, this is valid: implicit conversions to void * and back.
float f = 1.0f;
void *p = &f;
float *fp = p;
printf("*fp = %f\n", *fp);
// In C++, you have to use a cast:
float *fp = static_cast<float *>(p);
Void pointers have limitations: you cannot dereference them, and you cannot do any pointer arithmetic.
1: Function pointers should not be cast to void *.
Lets understand it with an example.
int main()
{
char i = 8;
int *ptr = &i;
printf("Value of i = %d", *ptr);
return 0;
}
Ans: It will print some garbage because it dereferenced 4 byte in memory.
so if you do char *ptr = &i;, it will dereference 1 byte and so on..
It will give correct answer.
Ok I understand the concept of pointers to pointers. But I don't know why this doesn't work.
void function(int **x)
{
*x = 10;
}
I keep getting the error:
a value of type "int" cannot be assigned to an entity of type "int*"
What am I doing wrong or what am I not understanding about pointers to pointers?
omg x_x I was confusing C with C++.
x is a pointer to a pointer so you have to dereference it twice to get to the actual object. E.g. **x = 10;
Ok I understand the concept of pointers to pointers.
Nah...
*x is an int*, so you can't assign an int to it.
The concept of pointers-to-pointers comes from C, where references aren't available. It allows reference semantics - i.e. you can change the original pointer.
In short, you need to dereference twice.
A dereference returns the thing a pointer is ponting to, so:
int n = 10; //here's an int called n
int* pInt = &n; //pInt points to n (an int)
int** ppInt = &pInt //ppInt points to pInt (a pointer)
cout << ppInt; //the memory address of the pointer pInt (since ppInt is pointing to it)
cout << *ppInt; //the content of what ppInt is pointing to (another memory address, since ppInt is pointing to another pointer
cout << *pInt; //the content of what pInt is pointing to (10)
cout << **ppInt; //the content of what the content of ppInt is pointing to (10)
x is pointing to a type of int *, not int. You either want to do static int i = 10; *x = &i or **x = 10.
i am using c++ and i have some trouble about pointers
i know that if we declare some variable
int t=7;
int *p=&t;
*p gives adress of variable t but in c++ here also definition of **s why it is used ?i have read it but i have some misunderstanding please can anybody give me example how use?let take about given example
Its a pointer to a pointer.
For example, if your operation was in a function:
void make_p(int **p, int *t) {
*p = t;
}
int main() {
int *p;
int t;
make_p(&p, &t);
}
For example, you can use this for creating an object in a function:
void create( Type** result )
{
*result = new Type();
}
//somewhere else in code
Type* object;
create( &object );
this doesn't make much sence for void functions creating a single object, but in case the function needs some predefined return type or needs to create more than one object that will make sence. A classic example is IUnknown::QueryInterface() that must return HRESULT:
HRESULT CYourClass::QueryInterface( IID& iid, void** result )
{
//inside you need to decide whether you know the iid passed, copy a pointer
// into *ppv and then return apropriate HRESULT
}
First of all *p will give you the value of variable t and not the address of t. Only 'p' will give you the address of t.
Essentially every address is just an integer number. If you are compiling for 32-bit architecture then it will be 32-bit long number and if you are compiling for 64-bit then it will be 64-bit long. This means that you can use a simple integer variable to store any variable's address irrespective of what type the variable is but it is better to use a proper type of pointer to store the variable's address. This way we can dereference the pointer and we dont have have to type cast it whenever we want to use the variable which is being pointed to.
To create a pointer to some variable, we declare a variable of the same type but put a '*' in front of the variable's name. For example you can declare an integer as follows
int a;
To create a pointer to 'a', create a new variable with the same type as a and just put a '*' in front of it. So the declaration of pointer to the above variable 'a' will look like
int *p;
Notice that other than an additional '*', its the same declaration. Now 'p' is a pointer to an integer variable.
Now consider that you want another pointer to point to this variable 'p'. Again you declare a variable similar to 'p' and just put a '*' in front of it. So a declaration of pointer to the above variable will look some thing like
int **pp;
Again notice that other than an extra '*' this declaration is very same to the declaration of 'p'. So the variable 'pp' is a pointer to a pointer to an integer
You can declare a pointer to 'pp' in the same way and the cycle will continue. This is also true for non simple types i.e pointers to variables of class or structure types are created the same way.
It's so we can change where other pointers are pointing to. Pointer to a pointer. Consider the following:
int *p1 = &j; // j is a int.
int *p2 = &k; // k is an int.
int **p;
p = &p1; //p points at p1.
*p = p2; //p1 now points to j because p2 is pointing to j.
//Also we can do this through just plain old variables.
int l;
*p = &l; //p1 is now pointing at l
Just as int *p; defines a pointer to an int, int **s; defines a pointer to (a pointer to an int). This comes up usually in two cases:
First, if you want an array that holds pointers to an int, you would do something like: int **arr = malloc(sizeof(int*) * arr_size);
Second, when a function needs to return more than one value, it's common to have the extra values returned by reference. I.e.:
/* Return x, y and error code. */
int getVals(int *px, int *py) {
*px = x;
*py = y;
return 0;
}
/* Return new object and error code. */
int newFoo(struct Foo **out_foo) {
struct Foo *f = malloc(sizeof(struct Foo));
f->value = 0;
*out_foo = f;
return 0;
}