Dereferencing 2d array [duplicate] - c++

I have the following code:
#include <iostream>
using namespace std;
int main()
{
int g[] = {9,8};
int (*j)[2] = &g;
cout << "*(j):" << *(j) << endl;
cout << "j:" << j << endl;
cout << "&j:" << &j << endl;
cout << "&(*j)" << &(*j) << endl;
cout << "*(*j):" << *(*j) << endl;
return 0;
}
which ouputs:
*(j):0x7fff5ab37c7c
j:0x7fff5ab37c7c
&j:0x7fff5ab37c70
&(*j)0x7fff5ab37c7c
*(*j):9
I think that j is a pointer to an array of two integer.
And &g is the address of the whole array.
Then j store the address of the whole array.
And so I use the *(j), it will dereference the first element in the array.
But the result said that *(j) store the array address the same value as j.
I cannot figure out how this happened.

I think that j is a pointer to an array of two integer.
And &g is the address of the whole array.
That is correct.
And so I use the *(j), it will dereference the first element in the array.
This is not. *j gives you the array itself. When you insert it to cout, it decays to a pointer again (this time to a pointer to its first element, type int*) and its value is printed.
It's in effect the same as if you wrote cout << g.

"I think that j is a pointer to an array"
Yes, it is. And that's also the reason why *j output the same address as outputting g would do. In this case an array decays into the pointer and that's why even outputting j yields the same result.
The fact that the same address is outputted might make you think that j and *j are the same pointers, however they are not. Their type is different (a fact that actually matters):
int g[] = {9,8}; // int[]
int (*j)[2] = &g; // int (*)[2]
so using *j becomes equivalent to using g directly, just like *(*j) becomes equivalent to *g.
And &(*j) is nothing but j, which is initialized with an address of an array (an address taken from decayed g, i.e. an address of the first element of this array).
So why j and *j outputs the same address and *(*j) outputs the value of first element?
Because of the type of j being int (*)[2]. A simple example:
int g[] = {9,8};
int (*j)[2] = &g; // j points to the first element as well
cout << *((int*) j);
outputs 9.

Related

A simple vector, how can I reassign the address for a new array correctly

I am trying to create a simple version of a vector. It seems to be working if I look only at what I am storing, but there is one thing that concerns me. Here is my code:
#include <iostream>
using namespace std;
int main(){
char* arr = new char[1];
int size = 1; // current size of the array
int num_chars = 0; // how many characters are stored so far
char c;
while (true)
{
cout << ">";
cin >> c;
if (c == '!') break;
if (num_chars == size)
{
size *= 2;
char* new_arr = new char[size];
cout << "Old array address: " << &arr << endl;
cout << "New array address: " << &new_arr << endl;
for (int i = 0; i < size/2; i++) // copy arr to new_arr
new_arr[i] = arr[i];
delete[] arr;
arr = new_arr;
}
arr[num_chars++] = c;
for (int i = 0; i < num_chars; i++)
cout << arr[i];
cout << endl;
cout << &arr << endl;
}
delete[] arr;
return 0;
}
the program accepts characters one at a time, and they are stored in an array which grows dynamically, finishing when you enter an exclamation mark. I added some cout statements to check my input and where the arrays are being stored.
When I allocate new_arr it gets a new address, then I copy over the memebers of arr to the new arr, delete arr, and assign arr to point to new_arr. The part that concerns me is that when I check the memory locations of arr after it gets reassigned, it's the same as it was before, so it looks like I'm just writing past the end of the original array. How can I correctly reassign the pointer to the new array?
Here is some sample output:
>a
a
0x7fff5fbff760
>b
Old array address: 0x7fff5fbff760
New array address: 0x7fff5fbff748
ab
0x7fff5fbff760
>c
Old array address: 0x7fff5fbff760
New array address: 0x7fff5fbff748
abc
0x7fff5fbff760
You are printing out addresses of pointers themselves, not addresses of the arrays (i.e. the contents of the pointers).
The location in memory where you store the address of the array (i.e. the address of variable arr) stays the same. It's not supposed to change. Thus, &arr is always the same. But the value stored in that location does change (as it would be expected).
Change the code to
cout << "Old array address: " << static_cast<void*>(arr) << endl;
and see the difference.
(static_cast<void*>(arr) casts type of arr from char* to void*. The reason to do this is that cout treats char* as a pointer to null-terminated string, and prints the contents of the string instead of the pointer's value. However, if we change the type of the pointer to something that cout does not interpret (e.g. void*), then cout will just print the address.)

2-D array without column number gives address?

int arr[][3] = {{1,3},{2,3},{6,7}};
cout << arr[0] << endl; // W/O col' somehow give you the address, not the element.
cout << arr[0][0] << endl;
I am curious as to why arr[0] prints the address, not the element.
It seems like somehow it's ignoring its dereference operator.
I'd be appreciated if you could help me in terms of a pointer or in depth.
Thank you.
Since arr is a two-dimensional array, arr[0] will give you an entire row (more precisely, the address of that row).
More precisely, since arr is of type int[][3] arr[0] is of type int[3], which decays to int *. Hence, cout << arr[0] << endl; prints a pointer.
array[0] holds the address of the array[0][0...n-1] values so only cout << arr[0]; prints the address since arr[0] is the pointer to the values in arr[0][0..n-1]
If you want specific value of an two dimensional array then you need to give both x and y index like
array[0][0] ... array[0][n-1]

different way to represent to a pointer to an array [duplicate]

This question already has answers here:
C pointer to array/array of pointers disambiguation
(13 answers)
Closed 8 years ago.
I have read the pointer to array c++
and have some experiment on it.
#include <iostream>
using namespace std;
int main()
{
int g[] = {9,8};
int (*j)[2] = &g;
int *i = g;
int n = (*j)[0];
int m = *(i + 0);
cout << "n:" << n << endl;
cout <<"m:" << m << endl;
cout << "=============" << endl;
cout << "*(j):" << *(j) << endl;//9's address ???
cout << "j:" << j << endl;//9's address ???
cout << "&j:" << &j << endl;//what it is???
cout << "&(*j)" << &(*j) << endl;//9's address ???
cout << "=============" << endl;
cout << "*(i):" << *(i) << endl;//get the value pointered by i
cout << "i:" << i << endl;//i's value store g's address
cout << "&i:" << &i << endl; //i's address
cout << "&(*i):" << &(*i) << endl;//9's address
cout << "=============" << endl;
cout << "*(g):" << *(g) << endl;//get the value pointered by g
cout << "g:" << g << endl;//g's value store 9's address
cout << "&g:" << &g << endl;//9's address???
cout << "&(*g):" << &(*g) << endl;//9's address
return 0;
}
The result is :
n:9
m:9
=============
*(j):0x7fff56076bbc
j:0x7fff56076bbc
&j:0x7fff56076bb0
&(*j)0x7fff56076bbc
=============
*(i):9
i:0x7fff56076bbc
&i:0x7fff56076ba8
&(*i):0x7fff56076bbc
=============
*(g):9
g:0x7fff56076bbc
&g:0x7fff56076bbc
&(*g):0x7fff56076bbc
[Finished in 0.3s]
What I want to ask is:
1.Why
int (*j)[2] = &g;
int *i = g;
if I change either one &g to g, or g to &g, it will give a compile error, what is the difference?
(I think that the array name is a pointer, so why cannot I use int (*j)[2] = g and what is the meaning of &g, it is a pointer already, why get address again?)
2.
Since the &g and g, their address are the same, why cannot be exchanged?
3.
Why the &g's value is 9's address? Is it store its own address?
4.
Can you explain the j variable part?
I cannot understand why j stores the 9's address and *(j) gets the 9's address, &(*j) gets the 9's address too?
I am very confused about it now. What I totally understand is about the i variable part,
g variable part is confused about the &g, and the j varialbe part is all confused.
The int (*j)[2] = &g; part is confused too.
You can have a look at this post to understand why g and &g hold the same address:
How array name has its address as well as its first element in it?
The compiler complains when you change either of g to &g because there is a type mismatch. This means that semantically, g and &g have different meanings, even though they may refer to the same thing: g, when used in an expression, decays into pointer to int (int *), but &g is of type pointer to array of 2 ints. These are not compatible types; you can't assign a pointer to an array of ints to something that is a pointer to int (and the same happens the other way around).
Your claim that g is already a pointer is wrong: g is an array. When used in an expression, it decays into a pointer to the array's first element. A pointer is just something that holds an address; an array is an address (the address of its first element). With &g, you get a pointer to an array, you don't get pointer to pointer because arrays do not decay into pointers when the referencing operator is used. Think of it like this: if an array is an address, then applying the "address of" operator - & - yields this same address, which is, by convention, the address of the first element. When you don't apply the & operator, in an expression, the array decays into a pointer to the first element, and then again - it points to the first element, the same address as &g.
g is the variable (in this case array), &g is the address of the variable (in this case the address of the beginning of the array. You might understand that, but the compiler does not, and thus it's giving you an error.
They probably could be exchanged, if you were willing to do type-casting, but that's not a really good idea in this case.
Because g is the array of integers, and the address of the first (0-th) element of that array just happens to be the address of the whole array. Doesn't it make sense?
j in your case is a pointer to the array, of course it is also a pointer to the address with the 0-th element of that array (by definition)
(*j)[2] is pointer to array of 2 integers. In other words it is (almost) equivalent with pointer to pointer to ints. The line int (*j)[2] = g; tries to assign int* to (int**) which is a type mismatch. The line int *i = &g; tries to assign int** to int* which is again a type mismatch.
(I think that the array name is a pointer, so why cannot I use int (*j)[2] = g and what is the meaning of &g, it is a pointer already, why get address again?)
The address of what? In its type checking C++ distinguishes address of variables of different types, so even though int* and int** are both addresses (pointers) they point to different types.

pointer to an int array gives the same address as when it is dereferenced

I have the following code:
#include <iostream>
using namespace std;
int main()
{
int g[] = {9,8};
int (*j)[2] = &g;
cout << "*(j):" << *(j) << endl;
cout << "j:" << j << endl;
cout << "&j:" << &j << endl;
cout << "&(*j)" << &(*j) << endl;
cout << "*(*j):" << *(*j) << endl;
return 0;
}
which ouputs:
*(j):0x7fff5ab37c7c
j:0x7fff5ab37c7c
&j:0x7fff5ab37c70
&(*j)0x7fff5ab37c7c
*(*j):9
I think that j is a pointer to an array of two integer.
And &g is the address of the whole array.
Then j store the address of the whole array.
And so I use the *(j), it will dereference the first element in the array.
But the result said that *(j) store the array address the same value as j.
I cannot figure out how this happened.
I think that j is a pointer to an array of two integer.
And &g is the address of the whole array.
That is correct.
And so I use the *(j), it will dereference the first element in the array.
This is not. *j gives you the array itself. When you insert it to cout, it decays to a pointer again (this time to a pointer to its first element, type int*) and its value is printed.
It's in effect the same as if you wrote cout << g.
"I think that j is a pointer to an array"
Yes, it is. And that's also the reason why *j output the same address as outputting g would do. In this case an array decays into the pointer and that's why even outputting j yields the same result.
The fact that the same address is outputted might make you think that j and *j are the same pointers, however they are not. Their type is different (a fact that actually matters):
int g[] = {9,8}; // int[]
int (*j)[2] = &g; // int (*)[2]
so using *j becomes equivalent to using g directly, just like *(*j) becomes equivalent to *g.
And &(*j) is nothing but j, which is initialized with an address of an array (an address taken from decayed g, i.e. an address of the first element of this array).
So why j and *j outputs the same address and *(*j) outputs the value of first element?
Because of the type of j being int (*)[2]. A simple example:
int g[] = {9,8};
int (*j)[2] = &g; // j points to the first element as well
cout << *((int*) j);
outputs 9.

C++ incrementing a pointer to an array

int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int (*parr)[10] = &arr;
//prints address of arr and the value 1
cout << parr << " " << *parr[0];
//what is this doing?
parr++;
//prints (what looks like the address of arr[1]) and some long number -8589329222
cout << parr << " " << *parr[0];
I thought parr++ would increment the address that parr is pointing to so that *parr[0] is now the address of *parr[1]. Where am I wrong?
You're assuming parr++ increments by one word. It doesn't. It increments by the size of *parr, which in thise case is an int[10], so it's incrementing by the size of 10 integers (probably 40 bytes).
You only need a pointer to the start of the array.
int* parr = arr; // points to the 0 element
parr++; // poInts to the first element, 1.