Can assign a pointer to a value on declaration? Something like this:
int * p = &(1000)
Yes, you can initialize pointers to a value on declaration, however you can't do:
int *p = &(1000);
& is the address of operator and you can't apply that to a constant (although if you could, that would be interesting). Try using another variable:
int foo = 1000;
int *p = &foo;
or type-casting:
int *p = (int *)(1000); // or reinterpret_cast<>/static_cast<>/etc
What about:
// Creates a pointer p to an integer initialized with value 1000.
int * p = new int(1000);
Tested and works. ;-)
There are two things not clear in the question to me. Do you want to set the pointer to a specific value (i.e address), or do you want to make the pointer point to some specific variable?
In the latter case, you can just use the address-of operator. The value of the pointer is then set to the address of some_int_variable.
int *p = &some_int_variable;
*p = 10; // same as some_int_variable = 10;
Note: What follows is evil changing of the pointer's value manually. If you don't know whether you want to do that, you don't want to do it.
In the former case (i.e setting to some specific, given address), you can't just do
int *p = 1000;
Since the compiler won't take the int and interpret it as an address. You will have to tell the compiler it should do that explicitly:
int *p = reinterpret_cast<int*>(1000);
Now, the pointer will reference some integer (hopefully) at address 1000. Note that the result is implementation defined. But nevertheless, that are the semantics and that is the way you tell the compiler about it.
Update: The committee fixed the weird behavior of reinterpret_cast<T*>(0) that was suggested by a note and for which i provided a workaround before. See here.
Um. I don't think you can take a non-const address of a constant like that.
but this works:
int x = 3;
int *px = &x;
cout << *px; // prints 3
or this:
const int x = 3;
const int *px = &x;
const int *pfoo = reinterpret_cast<const int*>(47);
Related
What is the difference between int* i and int** i?
Pointer to an integer value
int* i
Pointer to a pointer to an integer value
int** i
(Ie, in the second case you will require two dereferrences to access the integer's value)
int* i : i is a pointer to a object of type int
int** i : i is a pointer to a pointer to a object of type int
int*** i : i is a pointer to a pointer to a pointer to object of type int
int**** i : i is a pointer to a pointer to a pointer to a pointer to object of type int
...
int* pi
pi is a pointer to an integer
int **ppi
ppi is a pointer to a pointer to an integer.
EDIT :
You need to read a good book on pointers. I recommend Pointers on C by Kenneth Reek.
Let's say you're a teacher and have to give notes to one of your students.
int note;
Well ... I meant the whole class
int *class_note; /* class_note[0]: note for Adam; class_note[1]: note for Brian; ... */
Well ... don't forget you have several classes
int **classes_notes; /* classes_notes[0][2]: note for Charles in class 0; ... */
And, you also teach at several institutions
int ***intitute_note; /* institute_note[1][1][1]: note for David in class 1 of institute 1 */
etc, etc ...
I don't think this is specific to opencv.
int *i is declaring a pointer to an int. So i stores a memory address, and C is expecting the contents of that memory address to contain an int.
int **i is declaring a pointer to... a pointer. To an int. So i contains an address, and at that memory address, C is expecting to see another pointer. That second memory address, then, is expected to hold an int.
Do note that, while you are declaring a pointer to an int, the actual int is not allocated. So it is valid to say int *i = 23, which is saying "I have a variable and I want it to point to memory address 23 which will contain an int." But if you tried to actually read or write to memory address 23, you would probably segfault, since your program doesn't "own" that chunk of RAM. *i = 100 would segfault. (The solution is to use malloc(). Or you can make it point to an existing variable, as in int j = 5; int *i = &j)
Imagine you have a few friends, one of them has to give you something (a treasure... :-)
Say john has the treasure
int treasure = 10000; // in USD, EUR or even better, in SO rep points
If you ask directly john
int john = treasure;
int you = john;
If you cannot join john, but gill knows how to contact him,
int john = treasure;
int *gill = &john;
int you = *gill;
If you cannot even join gill, but have to contact first jake who can contact gill
int john = treasure;
int *gill = &john;
int **jake = &gill;
int you = **jake;
Etc... Pointers are only indirections.
That was my last story for today before going to bed :-)
I deeply believe that a picture is worth a thousand words. Take the following example
// Finds the first integer "I" in the sequence of N integers pointed to by "A" .
// If an integer is found, the pointer pointed to by P is set to point to
// that integer.
void f(int N, int *A, int I, int **P) {
for(int i = 0; i < N; i++)
if(A[i] == I) {
// Set the pointer pointed to by P to point to the ith integer.
*P = &A[i];
return;
}
}
So in the above, A points to the first integer in the sequence of N integers. And P points to a pointer that the caller will have the pointer to the found integer stored in.
int Is[] = { 1, 2, 3 };
int *P;
f(3, &Is[0], 2, &P);
assert(*P == 2);
&P is used to pass the address of P to the function. This address has type int **, because it's the address of a pointer to int.
int* i is the address of a memory location of an integer
int** is the address of a memory location of an address of a memory location of an integer
int* i; // i is a pointer to integer. It can hold the address of a integer variable.
int** i; // i is a pointer to pointer to integer. It can hold address of a integer pointer variable.
Neither is a declaration. Declaration syntax does not allow () around the entire declaration. What are these () doing there? If this is supposed to be a part of function declaration, include the whole function declaration thing in your question, since in general case the actual meaning of a declaration might depend on that. (Not in this one though.)
As for the difference... There is one * in the first and there are two *s in the second. Does it help? Probably not. The first one declares ias a pointer to int. The second one declares i as a pointer to int *. Does this help? Probably not much either. Without a more specific question, it is hard to provide a more meaningful answer.
Provide more context, please. Or, if this is actually as specific as it can get, read your favorite C or C++ book about pointers. Such broad generic questions is not something you ask on the net.
Note that
int *i
is not fully interchangeable with
int i[]
This can be seen in that the following will compile:
int *i = new int[5];
while this will not:
int i[] = new int[5];
For the second, you have to give it a constructor list:
int i[] = {5,2,1,6,3};
You also get some checking with the [] form:
int *i = new int[5];
int *j = &(i[1]);
delete j;
compiles warning free, while:
int i[] = {0,1,2,3,4};
int j[] = {i[1]};
delete j;
will give the warnings:
warning C4156: deletion of an array expression without using the array form of 'delete'; array form substituted
warning C4154: deletion of an array expression; conversion to pointer supplied
Both of these last two examples will crash the application, but the second version (using the [] declaration type) will give a warning that you're shooting yourself in the foot.
(Win32 console C++ project, Visual studio 2010)
Textual substitution is useful here, but beware of using it blindly as it can mislead you (as in the advanced example below).
T var; // var has type T
T* var; // var has type "pointer to T"
This works no matter what T is:
int* var; // pointer to int
char* var; // pointer to char
double* var; // pointer to double
// advanced (and not pure textual substitution):
typedef int int3[3]; // confusing: int3 has type "array (of size 3) of ints"
// also known as "int[3]"
int3* var; // pointer to "array (of size 3) of ints"
// aka "pointer to int[3]"
int (*var)[3]; // same as above, note how the array type from the typedef
// gets "unwrapped" around the declaration, using parens
// because [] has higher precedence than *
// ("int* var[3];" is an array (size 3) of pointers to int)
This works when T is itself a pointer type:
typedef int* T; // T is a synonym for "pointer to int"
T* var; // pointer to T
// which means pointer to pointer to int
// same as:
int** var;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I want to change different pointer (different types), that they point to NULL/0/nullptr..., but I have to use a variable to do this! Generally I understand pointers and I know what the problem is, but I don't know how to solve it.
So I need something like
int NULLPOINTER = nullptr; // data type can change if needed
int* myIntPointer = NULLPOINTER;
float* myFloatPointer = NULLPOINTER;
foo* myFooPointer = NULLPOINTER;
As shown above, this is not possible because of the invalid conversion error (int to int*/float*/foo*).
So how can I archiv this?
As requested a more complex example for clarification:
class foo
{
float floatVar;
};
class bar
{
char charVar;
};
void changeSomething(bar* pBarTmp)
{
/* pGlobal is a member of another class and the type is depends on the method */
pGlobal = pBarTmp;
}
int main()
{
/* Working just fine */
int var = 1;
int *pointer = &var;
/* Also working fine */
foo *pointer = 0; //nullptr or NULL or __null (compiler dependend)
/* Not working because newAddress is int and not bar* / foo* / int* */
int newAddress = 0;
// Only one of the following is present, it depends on the
// method/class (just for visualization)
bar *pointer = newAddress;
foo *pointer = newAddress;
int *pointer = newAddress;
changeSomething (pointer);
}
I am not allowed to change int newAddress; into int* newAddress;. Overall I won't use something else than NULL / 0 / nullptr / ...
Another difficulty is, that I cannot use reinterpret_cast cause of coding guidelines.
int* p3 = 1; //Error invalid conversion from int to int
You can directly set the address of a pointer in C++
int* p3 = reinterpret_cast<int*>( 0x00000001 );
But its not good idea since you dont know where the pointer points in memory and de-referencing would lead to undefined behavior.
Its invalid conversion because 1 has type int and it's not possible to assign to pointer variable int * without cast.
int* p2 = 0; //p is a NULL-pointer
Pointers pointing to null should be initialized
int* p2 = nullptr;
instead of
int* p2 = 0;
Since C++11 you can create an instance of std::nullptr_t and assign it to pointers.
std::nullptr_t initAddr;
int* p2 = initAddr;
C++11 came with nullptr, and nullptr has type std::nullptr_t. You can create an instance of this and assign:
int* p1;
char* p2;
double* p3;
std::nullptr_t newAddress;
p1 = newAddress;
p2 = newAddress;
p3 = newAddress;
Demo
This satisfies having your NULL in a variable.
Changing the adress a pointer is pointing to
My goal is to change the adress of different pointer types to NULL
By assignment:
int* p = nullptr;
and I have to use a variable to do this.
int newAdress = 0;
int* p2 = newAdress;
The bug here is that newAdress has the wrong type. The compiler helps you out by telling you that is wrong. You will need to use a pointer (of compatible type) variable to assign a pointer:
int* newAdress = nullptr;
// ^ see here, a pointer
int* p2 = newAdress;
int* p3 = 1;
This assignment makes little sense in most cases. 1 is not null, nor is there usually a guarantee that there is an int object at that memory location.
Nevertheless, there are some special cases where you need a particular address value. That can be achieved with casting:
int* p3 = reinterpret_cast<int*>(1);
If you don't know of such cases, then you don't need to do it. If you don't have such case, then using pointer to the arbitrary memory location has undefined behaviour.
You have to understand that int* ≠ int. You shouldn't directly change the address. That seems pointless, since every program run variables are saved in different parts of memory with different addresses.
It only works with NULL, which is the same as 0, but should be avoided in C++ 11, where you should use nullptr for safety.
What you can do is set the address with the address-of-operator &:
int a;
int* b = &a;
So I am trying to understand pointers and references.
Lets say we have the following:
int val = 100;
int *ip = &val;
Why is that not the same as simply pointing to val like this:
int val = 100;
int *ip = val;
Neither one of your two examples contains a pointer to reference:
The first example has a pointer to int, properly initialized using the address-of operator &
The second example has a pointer to int, improperly initialized to the value of val itself
Generally, you do not assign values to pointers directly: normally, you want an address-of operator, an implicit pointer conversion, or some pointer arithmetic. Although assigning a well-known address on specific hardware is also possible, compiler toolchains often provide ways to keep this outside of your program. Hence, if you see an assignment int *ip = 100 it's almost certainly incorrect.
If you want a reference, declare it like this:
int val = 100;
int &ref = val;
Now you can make a pointer to that reference, like this:
int *ipRef = &ref;
Since ref represents an alias for val, ipRef would have the same value as ip from your example (demo).
Easy way to understand why they are not the-same if you do this your self.
int val = 100;
cout<<val<<endl;
You shoud get 100 as output.
Now try:
int val = 100;
cout<<&val<<endl;
You should get a 0x7ffc201cab0c or something similar as the outout.
If you access val with the "&", you are accessing the memory address of it.
If you access val without the "&", you are accessing the value of it.
Therefore if you do
int val = 100;
int *ip = val;
you will should get a warning or an error but assuming that you want to see it compile so you can figure out what would happen, this is what it you should do:
int val = 100;
int *ip;
*ip = val;
This is the-same as the previous code except that it will compile. You are creating a pointer and assigning a value to the pointer instead of assigning a memory address to it. The code is valid but has a run-time error. The pointer ip is NOT pointing anywhere before you assigned value to it.
To make it work properly, you can do:
int val = 100;
int *ip = new int;
*ip = val;
Now, you have a pointer with a memory address. The value of that pointer is val which is 100. That's the value NOT the memory address.
To conclude this, pointer must be initialized or it will have undefined behavior or even crash. You use the ref sign (&) or the new keyword to initialize pointers then you can assign assign values to it.
int val = 100;
int *ip = new int; //Create a new pointer and initilize it with a new memory address
*ip = val; //Assign the value from val(100) to the pointer
OR
int val = 100;
int *ip = &val; //Create a new pointer and initialize it by making it point to existing address of **val**
*ip = 200; //change the value in the **memory addresss to **200**
Now val changes to 200 too.
int otherValue = 500;
*ip = otherValue ; //change the value in the **memory address** to 500
Now val changes to 500 too.
CHANGE MEMORY ADDRESS WHERE ip IS POINTING
You can also change the memory address anytime.
Lets make p point to otherValue.
*ip = &otherValue; //Point p to otherValue memory address not value
*ip = 5; //Change the value of p to 5(no memory address change)
Now otherValue has 5 as the value. p points to otherValue memory address.
val is an integer, so you can not assign an int to a pointer that points to an int because is not the valid value, you will need the address (obtained with the & operator)
Because pointers and integers are different data types.
int *ip = &val;
This initialises one int* with another int* (the value obtained by taking the address of val).
int *ip = val;
This is an attempt to initialise an int* with an int, which is not allowed.
Note that your code examples do not contain any references.
I was surprised that c++ allows incrementing dereferenced pointer to a constant data, which it should not allow through a pointer to a const data. Consider the code:
#include<iostream>
#include<climits>
using namespace std;
int main(){
int x = 2;
const int *xPtr2 = &x;
*xPtr2++;
cout << x << endl;
}
But still the value of x is 2. That means *xPtr2 was not actually incremented. I also tried *xPtr2 = 3, but this time it shows compilation error. Why is it so?
Here the precedence of ++ is more than that of *. Hence
*xPtr2++
is equivalent to
*(xPtr2++)
Since xPtr2 is not a constant pointer but a pointer to constant data, incrementing xPtr2 and dereferencing it is fine in this case (but not others) and hence no compilation error is caused.
The ++ operator has precedence over dereferencing. Basically you're dereferencing the pointer that has been incremented.
For the behavior you're trying to accomplish, you should wrap the pointer in parens.
(*xPtr2)++;
Same goes for assigning - you're trying to assign an int to a int *. It would work with parens.
(*xPtr2) = 3;
See your example in ideone.
You have mentioned
dereferencing pointer to constant data
So, lets consider the following code
#include <stdio.h>
int main() {
const int foo = 0xdead;
int* bar = (int*) &foo;
*bar = 0xcafe;
printf("const int foo = %#x", foo);
return 0;
}
Output : const int foo = 0xcafe
In C, C++ const is just a compile time modifier for variables. This means that the compiler wants no modification to a const at compile time. At runtime there is no concept of const => all local variables are stored in stack, all static and global variables are stored in .data section. Thus you can dereference a const and modify it only at runtime
A very general question: I was wondering why we use pointer to pointer?
A pointer to pointer will hold the address of a pointer which in turn will point to another pointer. But, this could be achieved even by using a single pointer.
Consider the following example:
{
int number = 10;
int *a = NULL;
a = &number;
int *b = a;
int *pointer1 = NULL;
pointer1 = b; //pointer1 points to the address of number which has value 10
int **pointer2 = NULL;
pointer2 = &b; //pointer2 points to the address of b which in turn points to the address of number which has value 10. Why **pointer2??
return 0;
}
I think you answered your own question, the code is correct, what you commented isn't.
int number = 10; is the value
int *pointer1 = b; points to the address where int number is kept
int **pointer2 = &b; points to the address where address of int number is kept
Do you see the pattern here??
address = * (single indirection)
address of address = ** (double indirection)
The following expressions are true:
*pointer2 == b
**pointer2 == 10
The following is not!
*pointer2 == 10
Pointer to pointer can be useful when you want to change to what a pointer points to outside of a function. For example
void func(int** ptr)
{
*ptr = new int;
**ptr = 1337;
}
int main()
{
int* p = NULL;
func(&p);
std::cout << *p << std::endl; // writes 1337 to console
delete p;
}
A stupid example to show what can be achieved :) With just a pointer this can not be done.
First of all, a pointer doesn't point to a value. It point to a memory location (that is it contains a memory address) which in turn contains a value. So when you write
pointer1 = b;
pointer1 points to the same memory location as b which is the variable number. Now after that is you execute
pointer2 = &b;
Then pointer2 point to the memory location of b which doesn't contains 10 but the address of the variable number
Your assumption is incorrect. pointer2 does not point to the value 10, but to the (address of the) pointer b. Dereferencing pointer2 with the * operator produces an int *, not an int.
You need pointers to pointers for the same reasons you need pointers in the first place: to implement pass-by-reference parameters in function calls, to effect sharing of data between data structures, and so on.
In c such construction made sense, with bigger data structures. The OOP in C, because of lack of possibility to implement methods withing structures, the methods had c++ this parameter passed explicitly. Also some structures were defined by a pointer to one specially selected element, which was held in the scope global to the methods.
So when you wanted to pass whole stucture, E.g. a tree, and needed to change the root, or 1st element of a list, you passes a pointer-to-a-pointer to this special root/head element, so you could change it.
Note: This is c-style implementation using c++ syntax for convienience.
void add_element_to_list(List** list, Data element){
Data new_el = new Data(element); // this would be malloc and struct copy
*list = new_el; //move the address of list, so it begins at new element
}
In c++ there is reference mechanismm and you generally you can implement nearly anything with it. It basically makes usage of pointers at all obsolete it c++, at least in many, many cases. You also design objects and work on them, and everything is hidden under the hood those two.
There was also a nice question lately "Why do we use pointers in c++?" or something like that.
A simple example is an implementation of a matrix (it's an example, it's not the best way to implement matrices in C++).
int nrows = 10;
int ncols = 15;
double** M = new double*[nrows];
for(unsigned long int i = 0; i < nrows; ++i)
M[i] = new double[ncols];
M[3][7] = 3.1416;
You'll rarely see this construct in normal C++ code, since C++ has references. It's useful in C for "passing by reference:"
int allocate_something(void **p)
{
*p = malloc(whatever);
if (*p)
return 1;
else
return 0;
}
The equivalent C++ code would use void *&p for the parameter.
Still, you could imagine e.g. a resource monitor like this:
struct Resource;
struct Holder
{
Resource *res;
};
struct Monitor
{
Resource **res;
void monitor(const Holder &h) { res = &h.res; }
Resource& getResource() const { return **res; }
}
Yes, it's contrived, but the idea's there - it will keep a pointer to the pointer stored in a holder, and correctly return that resource even when the holder's res pointer changes.
Of course, it's a dangling dereference waiting to happen - normally, you'd avoid code like this.