Why is the result of using `int (*p)[5]` so confusing? - c++

I know that int (*p)[5] means a pointer which points to an array of 5 ints.
So I code this program below:
#include <iostream>
using namespace std;
int main()
{
int a[5]={0,1,2,3,4};
int (*q)[5]=&a;
cout<<a<<endl;
cout<<q<<endl;
cout<<*q<<endl;
cout<<**q<<endl;
return 0;
}
On my machine the result is:
0xbfad3608
0xbfad3608 //?__?
0xbfad3608
0
I can understand that *q means the address of a[0] and **q means the value of a[0], but why does q have the same value as a and *q? In my poor mind, it should be the address of them! I'm totally confused. Somebody please help me. Please!

Look at it this way:
q == &a
*q == a
**q == *a
You didn't try printing &a. If you do, you'll see that it has the same value as a. Since &a == a, and q == &a, and *q == a, by transitivity q == *q.
If you want to know why &a == a, check out Why is address of an array variable the same as itself?

q and &a are pointers to the array.
*q and a are "the array". But you can't really pass an array to a function (and std::ostream::operator<< is a function); you really pass a pointer to the first element, which is created implicitly (called pointer decay). So *q and a become pointers to the first element of the array.
The beginning of the array is at the same location in memory that the array is, trivially. Since none of the pointers involved are pointers-to-char (which are handled specially so that string literals will work as expected), the addresses just get printed out.

That because array is automatically converted to a pointer, which just has the value of the address of the array. So when you are trying to print print the array using <<a or <<*q, you are in fact printing its address.

Related

What is the difference between int* p and int** p in c++? [duplicate]

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;

How is it possible that a null pointer still retains a memory adress?

When you initialize a pointer with nothing(NULL), that element still has a memory address big enough for the initialising type of that pointer(4 bytes for int, 1 for char etc.) but why,since it's tehnically nothing, not even the value zero? I mean, NULL can't be a fixed value like 0 because zero still is considered a value, so it is something more than that?
Example:
#include <iostream>
int *a=NULL;
int main()
{
std::cout <<&a; //it will show the address in hexadecimal system;
return 0;
}
Your program does not answer the question you were asking. This program shows that, yes the pointer has an address, it needs one to store the value (the address it is pointing to). When you print the value you see that it is indeed nullptr (since this is C++ not C).
#include <iostream>
int *a= nullptr;
int main()
{
std::cout << &a << '\n'; // Will show the address OF THE POINTER in hexadecimal system;
std::cout << a << '\n'; // Will show the address at a is pointing to.
return 0;
}
Output:
0x601180
0
I'm pretty sure there's a duplicate, but I don't see any now. You confuse the meaning of operators * and & in different contexts.
Here, &p means "address of p". And what is p? p is a global variable of pointer type. It is perfectly valid to take address of any global variable.
So, to clear things up:
#include <iostream>
int *a=NULL;
int main()
{
std::cout << &a; //perfectly valid, address of p, type int** (pointer-to-pointer-to-int)
std::cout << a; //still valid, it gives address to where p is pointing, i.e. 0 (NULL)
std::cout << *a; //wrong, dereferencing an invalid address, there's no memory allocated
return 0;
}
You also seem to have few misconceptions about pointers:
"that element still has a memory address big enough for the initialising type of that pointer(4 bytes for int, 1 for char etc.)"
Not at all. Pointer is just a pointer. It doesn't care where does it point to. In fact, on lower levels it's just plain int. It can point to an array, to an element, to nothing at all or to some wild place where nothing was ever stored.
"NULL can't be a fixed value like 0 because zero still is considered a value, so it is something more than that?"
Again, pointer is just a pointer. Pointer doesn't know anything at all about value. Value may or may not exist, and the memory where pointer points to may or may not be valid. And in fact, NULL is defined to be exactly 0 (or nullptr in newer standards): https://en.cppreference.com/w/cpp/types/NULL

Array of Pointers Pointing to an unknown location

I was practicing with array of pointers.
i wrote a simple code.
#include<iostream>
using namespace std;
int main(){
int a[3]={1,2,3};
int *b[3];
for(int i=0; i<3; i++){
b[i] = &a[i];
}
cout<<b; //This gives a confusing output
cout<<endl;
for(int i=0; i<3; i++){
cout<<b[i];
cout<<endl;
}
}
and Output is
0x6ffe10
0x6ffe30
0x6ffe34
0x6ffe38
Now I don't understand where the b pointing.
I know this sounds weird but i wanna know.
where the b pointer pointing.
The b[0], b[1], b[2] gives expected result.
b is an array of pointers to int. It's address is the address of the first pointer.
The first pointer b[0] is assigned the address of element a[0] (so b[0] points to 1).
b[1] is assigned the address of a[1] (so b[1] points to 2)
b[2] is assigned the address of a[2] (so b[2] points to 3)
In each case the pointer in the b array holds the address of the corresponding element within a. So if there are any changes made to the elements of a after your loop assigning the address in a to b, the value held in the memory location pointed to by the element of b will change, but the address for that value held by b will remain unchanged.
When b is passed to cout's << operator, it decays into a pointer; hence as far as the printing function is concerned, printing out b is the same as printing out &b[0].
Therefore, cout << b; prints out the address of the first pointer in the b[3] array. (Note that the address of the pointer is not the same thing as the address the pointer is pointing to! That can be a source of confusion -- just keep in mind that a pointer-variable is a variable as well, and like any other variable, it has its own unique location in memory, which is distinct from the location it is pointing at)
b is an array of pointers to int which is a local variable on the stack.
Its address does not depend on what individual elements of its array are assigned to.
If you print its value before the for loop (where you assign values to its members), you will see that it is the same as the value printed after the for loop.
See live demo here.
Pictorially:
b Memory adress of the whole array.

Trying to understand * and & in C++ [duplicate]

This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 7 years ago.
I have a few questions. This isn't homework. I just want to understand better.
So if I have
int * b = &k;
Then k must be an integer, and b is a pointer to k's position in memory, correct?
What is the underlying "data type" of b? When I output it, it returns things like 0x22fe4c, which I assume is hexadecimal for memory position 2293324, correct?
Where exactly is memory position '2293324'? The "heap"? How can I output the values at, for example, memory positions 0, 1, 2, etc?
If I output *b, this is the same as outputting k directly, because * somehow means the value pointed to by b. But this seems different than the declaration of b, which was declared int * b = k, so if * means "value of" then doesn't mean this "declare b to the value of k? I know it doesn't but I still want to understand exactly what this means language wise.
If I output &b, this is actually returning the address of the pointer itself, and has nothing to do with k, correct?
I can also do int & a = k; which seems to be the same as doing int a = k;. Is it generally not necessary to use & in this way?
1- Yes.
2- There's no "underlying data type". It's a pointer to int. That's its nature. It's as data type as "int" or "char" for c/c++.
3- You shouldn't even try output values of memory which wasn't allocated by you. That's a segmentation fault. You can try by doing b-- (Which makes "b" point to the "int" before it actual position. At least, to what your program thinks it's an int.)
4- * with pointers is an operator. With any data type, it's another data type. It's like the = symbol. It has one meaning when you put == and another when you put =. The symbol doesn't necesarilly correlates with it meaning.
5- &b is the direction of b. It is related to k while b points to k. For example, if you do (**(&b)) you are making the value pointed by the value pointed by the direction of b. Which is k. If you didn't changed it, of course.
6- int & a = k means set the direction of a to the direction of k. a will be, for all means, k. If you do a=1, k will be 1. They will be both references to the same thing.
Open to corrections, of course. That's how I understand it.
In answer to your questions:
Yes, b is a pointer to k: It contains the address of k in the heap, but not the value of k itself.
The "data type" of b is an int: Essentially, this tells us that the address to which b points is the address of an int, but this has nothing to do with b itself: b is just an address to a variable.
Don't try to manually allocate memory to a specific address: Memory is allocated based of the size of the object once initialized, so memory addresses are spaced to leave room for objects to be allocated next to each other in the memory, thus manually changing this is a bad idea.
* In this case is a de-reference to b. As I've said, b is a memory address, but *b is what's at b's address. In this case, it's k, so manipulating *b is the same as manipulating k.
Correct, &b is the address of the pointer, which is distinct from both k and b itself.
Using int & a = k is creating a reference to k, which may be used as if it were k itself. This case is trivial, however, references are ideal for functions which need to alter the value of a variable which lies outside the scope of the function itself.
For instance:
void addThree(int& a) {
a += 3;
}
int main() {
int a = 3; //'a' has a value of 3
addThree(a); //adds three to 'a'
a += 2; //'a' now has a value of 8
return 0;
}
In the above case, addThree takes a reference to a, meaning that the value of int a in main() is manipulated directly by the function.
This would also work with a pointer:
void addThree(int* a) { //Takes a pointer to an integer
*a += 3; //Adds 3 to the int found at the pointer's address
}
int main() {
int a = 3; //'a' has a value of 3
addThree(&a); //Passes the address of 'a' to the addThree function
a += 2; //'a' now has a value of 8
return 0;
}
But not with a copy-constructed argument:
void addThree(int a) {
a += 3; //A new variable 'a' now a has value of 6.
}
int main() {
int a = 3; //'a' has a value of 3
addThree(a); //'a' still has a value of 3: The function won't change it
a += 2; //a now has a value of 5
return 0;
}
There are compliments of each other. * either declares a pointer or dereferences it. & either declares a (lvalue) reference or takes the address of an object or builtin type. So in many cases they work in tandem. To make a pointer of an object you need its address. To use a pointer as a value you dereference it.
3 - If k is a local variable, it's on the stack. If k is a static variable, it's in the data section of the program. The same applies to any variable, including b. A pointer would point to some location in the heap if new, malloc(), calloc(), ... , is used. A pointer would point to the stack if alloca() (or _alloca()) is used (alloca() is similar to using a local variable length array).
Example involving an array:
int array_of_5_integers[5];
int *ptr_to_int;
int (*ptr_to_array_of_5_integers)[5];
ptr_to_int = array_of_5_integers;
ptr_to_array_of_5_integers = &array_of_5_integers;

Array base pointer and its address are same. Why?

Consider the following program.
#include <stdio.h>
int main()
{
int a[10]={0};
printf("%p %p\n", a, &a);
printf("%d %d\n", *a, *(&a));
return 0;
}
a and &a are same. But *a and *(&a) are not. I am out of answers. Please help.
a[i] is the same as *(a + i). So the first element is at the same address as the array itself.
You'll find a more detailed explanation in another question here on SO: How come an array's address is equal to its value in C?
There is no "array base pointer", i.e. there no pointer variable that points to the array. The name of the array refers to the array itself. Therefore you can not take an address of a, instead, &a is handled as a special case.
When you use the name of an array in an expression, it decays into a pointer that points to the first element of the array. However, & and sizeof operators are exceptions.
ANSI C specifies that &a means the address of the array itself, and its type is "pointer to array", not "pointer to array element".
In pre-ANSI compilers, &a would cause a warning.
The address of an array is one of those things you learn early on in C. The address of the buffer is the address of its first element. In the case of
printf("%d %d\n", *a, *(&a));
*a takes the value of a.
*(&a) first take's a's address, and then deferences from that.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char szBuffer[100];
char *pBufferPtr = NULL;
int main(int argc, char *argv[])
{
pBufferPtr = szBuffer;
printf("%s %i\n %s %i\n %s %i\n",
"szBuffer's address: ", (int ) szBuffer,
"&szBuffer[0]'s address: ", (int ) &szBuffer[0],
"pBufferPtr's address: ", (int ) pBufferPtr);
printf("\n%s\n", "Program ended.");
return 0;
}
As I learned many years ago, sometimes the best thing to do with pointers is write what used to be called "stub" code, and then examine in the debugger or use "print" (printf) statements. What gets trickier is when you want to modify what a pointer points to, instead of its contents.
a and &a have the same value, but they are different types: int * and int **. You should have got a warning when you compiled you code.
Your second line will work if you add an extra * like this:
printf("%d %d\n", *a, **(&a));
This does make sense: if *a dereferences a and gives the first element of the array, and &a means take the address of a, then *(&a) takes the address of a, dereferences that, and arrives back at a once more.