Pointers ! difference between two expressions - c++

I was wondering if anyone can tell me the difference between two expressions:
*(ptr+i) and *ptr+i
It is used in the code as follows:
char string[]="hello";
char *ptr;
ptr=string;
for(int i=0;string[i]!='\0';i++)
{
cout<<*(ptr+i); //*ptr+i
}

Let's say you have an array of 3 integers, with values 150, 200, and 250. In memory, this array would look like:
+----------+----------+----------+---
| 96000000 | c8000000 | fa000000 |...
+----------+----------+----------+---
| aka 150 | aka 200 | aka 250 |...
+----------+----------+----------+---
a (a+1) (a+2)
Now, you're not dealing with an array of integers here, but integers are somewhat easier to demonstrate.
Pointers and arrays are largely interchangeable in C/C++, so in the above example, think of a as a pointer. Already this means that string and ptr are essentially the same variable.
With that said, the difference between *(pointer+i) and *pointer+1 is what the 1 is applied to. In the first case, it is the pointer's address. In the second case, it is the value the pointer points to. To continue with the above example:
int x = *a+1; // x is 151
int y = *(a+1); // y is 200
int z = *(a+1)+1; // z is 201

Related

Pointer Problems : Assigning to 'int *' from incompatible type 'int

I've been reading the book "Jumping into C++", and am currently reading up on pointers. This is an exercise from the book:
"What are the final values in x, p_int, and p_p_int in the following code:
int x = 0;
int *p_int = & x;
int **p_p_int = & p_int;
*p_int = 12;
**p_p_int = 25;
p_int = 12;
*p_p_int = 3;
p_p_int = 27;
And I get the error:
"Assigning to int * from incompatible type int"
On the last three lines.
I don't know why this is happening, and would appreciate any insight.
Furthermore, assuming that this code somehow works, I would think that since all pointers are just pointing towards a single memory (**p_p_int -> *p_int -> x), the last value assignment would dictate the final value of the memory location. However in the book, the answer is:
x = 25, p_p_int = 27, p_int = 3
Is this correct? If so, could anyone explain this to me?
As you can see p_int has as static type int *, and on the last three line you are doing something like
p_int = 12;
where 12 is an int, and so can't be assigned to a pointer (same thing to the other 2 lines)
However, x p_int p_p_int have different values because x contains the integer value, p_int the address of x and p_p_int the address of p_int.
Also keep in mind that this is a """"compilable"""" C code, not C++, but you will get 3 warnings also on C compiler telling you that you are assigning to a pointer an incompatible type
This part:
p_int = 12;
*p_p_int = 3;
p_p_int = 27;
There is no way this compiles with any confirming C++ compiler. It is just ill-formed. Even if you used casts to make it work, you'd cause undefined behavior. Try a different book.
int *p_int = & x;
int **p_p_int = & p_int;
These lines all point to the same memory in location (variable x).
There are three variables in your code snippet. Here is a table showing the value each variable would have after the execution of each of the lines (if the code were to actually compile).
| x | p_int | p_p_int |
-------------------------+----+-------+---------|
int x = 0; | 0 | undef | undef |
int *p_int = & x; | 0 | &x | undef |
int **p_p_int = & p_int; | 0 | &x | &p_int | <-- begin: all variables lead to x
-------------------------+----+-------+---------|
*p_int = 12; | 12 | &x | &p_int |
**p_p_int = 25; | 25 | &x | &p_int |
-------------------------+----+-------+---------| <-- end: all variables lead to x
p_int = 12; | 25 | 12 | &p_int | <-- p_int now points to garbage
*p_p_int = 3; | 25 | 3 | &p_int |
-------------------------+----+-------+---------|
p_p_int = 27; | 25 | 3 | 27 | <-- p_p_int now points to garbage
------------------------------------------------/
I've used undef to indicate that the variable does not yet exist (i.e. is undefined); &x and &p_int to represent the addresses of those variables (since an exact value is not knowable).
This is a thought exercise to see if you understand different levels of indirection, if you realize that *p_int and p_int refer to different values in memory. As you noticed, it does not compile. Assigning a numeric literal to a pointer is almost certainly an error, of no use outside this sort of thought experiment. In real code, a line like p_int = 12 is probably a typo (likely intended to be *p_int = 12) and the compiler will alert you to this.
Fortunately, the author seems to be aware of the inadvisability of trying to access the memory at addresses 12, 3, and 27, as neither p_int nor p_p_int was de-referenced while storing a bogus address. Still, it would be nice if the author acknowledged these limitations, or better yet devised an exercise that does not need such a disclaimer. (Hopefully this was an isolated slip. Unlike some people, I would not denounce an entire book on the basis of a single exercise. Books are long, C++ is complex, and mistakes happen. )

Work with vector of struct with int** as a member [duplicate]

Activity solution[a][b];
...
Activity **mother = solution;
I want to convert 2D array of objects to pointer-to-pointer. How can I do this;
I searched it on google. however I found only one dimension array example.
A mere conversion won't help you here. There's no compatibility of any kind between 2D array type and pointer-to-pointer type. Such conversion would make no sense.
If you really really need to do that, you have to introduce an extra intermediate "row index" array, which will bridge the gap between 2D array semantics and pointer-to-pointer semantics
Activity solution[a][b];
Activity *solution_rows[a] = { solution[0], solution[1] /* and so on */ };
Activity **mother = solution_rows;
Now accessing mother[i][j] will give you access to solution[i][j].
The reason you can do this for one-dimensional arrays and not two-dimensional arrays has to do with the way in which the actual array elements are stored in memory. For one-dimensional arrays, all of the elements are stored consecutively, so the expression array[i] is equivalent to the expression *(array + i). As you can see, the array size is not needed to perform an array index operation. However, for two-dimensional arrays, the elements are stored in "row major" order, meaning that all of the elements in the zeroth row are stored first, followed by the elements in the first row, followed by the elements in the second row, etc. Therefore, the expression array[i][j] is equivalent to *(array + (i * ROW_SIZE) + j), where ROW_SIZE is the number of elements in each row. Therefore, the array's row size is needed to perform an array index operation, and casting the array variable to a pointer loses that information.
This is c++! Everything is possible! But a this is c++ so it requires some level of understanding.
To that end let's start with a simple example of 2 1-dimensional arrays: char firstName[4] = { 'J', 'o', 'n', '\0' } and char lastName[4] = { 'M', 'e', 'e', '\0' } Let's look at a possible memory layout here:
+------------+-------+
| Address | Value |
+------------+-------+
| 0x76543210 | 0x4A | <- firstName[0] - 'J'
| 0x76543211 | 0x6F | <- firstName[1] - 'o'
| 0x76543212 | 0x6E | <- firstName[2] - 'n'
| 0x76543213 | 0x00 | <- firstName[3] - '\0'
+------------+-------+
| 0x76543214 | 0x4D | <- lastName[0] - 'M'
| 0x76543215 | 0x65 | <- lastName[1] - 'e'
| 0x76543216 | 0x65 | <- lastName[2] - 'e'
| 0x76543217 | 0x00 | <- lastName[3] - '\0'
+------------+-------+
Given this memory layout if you were to do cout << firstName << ' ' << lastName you'd get:
0x76543210 0x76543214
These arrays are really just a pointer to their first element! This illustrates Array to Pointer Decay, which you can read more about here: http://en.cppreference.com/w/cpp/language/array#Array-to-pointer_decay
Before we move on there's something important here to note, chars take up exactly 1-byte so the address of each subsequent char in the array will simply be the next address. That's leveraged by the Subscript Operator in this way: firstName[1] is equivalent to *(firstName + 1). This is true for chars but is also true for any other type which takes up more than 1-byte. Let's take for example: short siArray = { 1, 2, 3, 4 }, a possible memory layout of siArray would look like:
+------------+--------+
| Address | Value |
+------------+--------+
| 0x76543218 | 0x0001 | <- siArray[0] - 1
| 0x7654321A | 0x0002 | <- siArray[1] - 2
| 0x7654321C | 0x0003 | <- siArray[2] - 3
| 0x7654321E | 0x0004 | <- siArray[3] - 4
+------------+--------+
Even though cout << siArray << ' ' << &(siArray[1]) will output:
0x76543218 0x7654321A
*(siArray + 1) will still index the same element of siArray as siArray[1]. This is because when doing pointer arithmetic c++ considers the type of the address being operated on, thus incrementing a short* will actually increase the address by sizeof(short). You can read more about pointer arithmetic here: http://en.cppreference.com/w/cpp/language/operator_arithmetic
Lastly let's look at how c++ stores 2-dimensional arrays. Given: char name[2][4] = { { 'J', 'o', 'n', '\0' }, { 'M', 'e', 'e', '\0' } } a possible memory layout would be:
+------------+-------+
| Address | Value |
+------------+-------+
| 0x76543220 | 0x4A | <- name[0][0] - 'J'
| 0x76543221 | 0x6F | <- name[0][1] - 'o'
| 0x76543222 | 0x6E | <- name[0][2] - 'n'
| 0x76543223 | 0x00 | <- name[0][3] - '\0'
| 0x76543224 | 0x4D | <- name[1][0] - 'M'
| 0x76543225 | 0x65 | <- name[1][1] - 'e'
| 0x76543226 | 0x65 | <- name[1][2] - 'e'
| 0x76543227 | 0x00 | <- name[1][3] - '\0'
+------------+-------+
Since we know an 1-dimensional array value is really just a pointer, we can see from this memory layout that name[0] is not a pointer, it's just the first character of the first array. Thus name does not contain 2 1-dimensional array pointers, but contains the contents of the 2 arrays. (Incidentally on a 32-bit machine not storing the pointers saves 8-bytes of memory, which is pretty substantial for an 8-byte 2-dimensional array.) Thus trying to treat name as a char** would try to use the characters as a pointer.
Having understood this we really just need to avoid using c++'s pointer arithmetic to find dereference the value. To do that we'll need to work with a char* so that adding 1 is really just adding 1. So for example:
const short si2DArray[2][3] = { { 11, 12, 13 }, { 21, 22, 23 } };
const auto psi2DPointer = reinterpret_cast<const char*>(si2DArray);
for(auto i = 0U; i < size(si2DArray); ++i) {
for(auto j = 0U; j < size(*si2DArray); ++j) {
cout << *reinterpret_cast<const short*>(psi2DPointer + i * sizeof(*si2DArray) + j * sizeof(**si2DArray)) << '\t';
}
cout << endl;
}
Live Example
Note that in this example even though I reference si2DArray thought psi2DPointer I'm still using information from si2DArray to do the indexing, namely:
How many arrays are in the major dimension: size(si2DArray)
How many elements are in the minor dimension: size(*si2DArray)
What is the size in memory of the minor dimension: sizeof(*si2DArray)
What is the element type of the array: sizeof(**si2DArray)
You can thus see that the loss of information from converting from an array to a pointer is substantial. You may be tempted to preserve the element type, thereby also simplifying the pointer arithmetic. It's worthwhile to note that only a conversion to char* is considered defined behavior by reinterpret_cast: http://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing
I want to convert 2D array of objects to pointer-to-pointer. How can I do this?
Why? Is it because an interface expects a pointer to pointers?
If so, you'll need to create a new array that contains those pointers.
Activity solution[a][b];
Activity* solutionPtrs[a];
for (int i = 0; i < a; ++i)
solutionPtrs[a] = solution[a];
Activity** mother = solutionPtrs;
Why can't you just cast a 2D array of T to T**? Well, because they have nothing to do with one another!
You can cast a T[a] to a T* because you get a pointer to the first element of the array.
You can do this with 2D arrays as well, but if you have a T[a][b] then it decays to a (T[b])* because a 2D array is not an array of pointers, it's an array of arrays.
Not sure if you were looking for something like this. You should provide more details about what you want to achieve. They are fundamentally different types. One solution is to below.
For the record, if someone finds it useful:
// define matrix
double A[3][3] = {
{ 1, 2, 3},
{ 4, 5, 6},
{ 7, 8, 9}
};
// allocate memory
double ** A_ptr = (double **) malloc(sizeof (double *) * 3);
for (int i = 0; i < 3; i++)
A_ptr[i] = (double *) malloc(sizeof (double) * 3);
// copy matrix
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
A_ptr[i][j] = A[i][j];
printf(" %f ", A_ptr[i][j]);
}
}
You can't. They are fundamentally different types.

Understanding address of values and dereferecing pointers

I'm trying to have a better understanding of pointers and how they work. I'm also trying to understand the idea of dereferencing pointers. This is my understanding of pointers, and what may be possible of pointers.
This is a table representing 3 cells of memory. In each cell there is an address, cell name, and value.
+---------------------------+
| 1672 x | 1673 y | 5 |
| 1673 | 5 | 65 |
+---------------------------+
This is the initialization for the three cell blocks, assuming address 5 hasn't been initialized.
int x = 1673;
int y = 5;
This is how pointers are commonly used.
int* p_x = &x; //&x == 1672);
*p_x == 1673;
This would be true if you forgot to place ampersand in from of variable name.
int* p_y = y; //y == 5);
*p_y == 65;
If everything else is true would this also be true? If you were using the pointer to the address of x for a simple return on a member function, could you just skip a declaration of the pointer and just send the dereferenced address?
*&x == &y;
The lines with == will not compile, and are not actual c++ code. They are just an effective way to show equivalency.

Issue with a char* array

Okay so I have:
char* arr[5];
and I have
char input[10];
and then:
int i = 0;
cin.getline(input, 10);
while(input[0] != 'z')
{
arr[i] = input;
cin.getline(input, 10);
i++;
}
the result is that every element in arr is the same because they are all pointers to input, but I want each element to point to char arrays that the input variable held at that given time.
result that this brings:
arr[0] = line beginning in 'z' (because that is what input currently is holding)
arr[1] = line beginning in 'z'
arr[2] = ... and so on
result that I want:
arr[0] = first line read in
arr[1] = second line read in
arr[2] = third line read in and so on...
I am confused about how I can get the elements to all point to new values instead of all be pointing to the same value.
If you want to take input 5 times,you can try this code segment
int i = 0;
while(i<5)
{
arr[i] = input;
cin.getline(input, 10);
i++;
}
this should work and you can get your "desired result" as you stated above.
Edit:
This will not work, as described in the comment. See example here: http://ideone.com/hUQGa7
What is required are different pointer values occupying each of the elements in arr. How to achieve those different pointer values is discussed in the other answers given.
Let's talk characters and pointers.
Given a character:
+---+
+ A +
+---+
A pointer to the character, char *, points to the character. That's it, nothing more.
An array of characters is a container that has slots for characters. A pointer to the array often points to the first character of the array. Here's where the problem comes in.
Many functions require a pointer, to the first character of the array, but either don't say that it's to the first character or require a pointer to a single character, assuming that the pointer is the first character in the array.
Pointers need something to Point at
You have allocated an array of pointers, but haven't allocated the memory for each pointer:
Array
+-----+ +----+---+---+
| | --> | | | |
| | +----+---+---+
+-----+
| | +----+---+---+
| | --> | | | |
| | +----+---+---+
+-----+
The content of the array are pointer. So you will need to allocate memory and place the pointer into the array:
arr[0] = new char [11]; // +1 for the nul terminator character.
char text[33];
arr[1] = text;
So what you aim to do is:
cin.getline(arr[0], 10);
cin.getline(arr[1], 33);
Strings are soooo much easier to deal with. They manage their own memory:
std::string array_text[5]; // An array of 5 string.
getline(cin, array_text[0]);
The next step is to use a vector and you are all caught up:
std::vector< std::string > text_vector(5); // Pre-allocate 5 slots.
getline(cin.text_vector[2]);
You have to copy the data of input everytime.
You can do like this in while loop:
while(input[0] != 'z')
{
arr[i] = new char[strlen(input)];
strcpy(arr[i], input);
cin.getline(input, 10);
i++;
}
And since you have defined arr to be of length 5. So you have to check in the while loop that i doesn't exceed the value 5. i<5.

conversion of 2D array to pointer-to-pointer

Activity solution[a][b];
...
Activity **mother = solution;
I want to convert 2D array of objects to pointer-to-pointer. How can I do this;
I searched it on google. however I found only one dimension array example.
A mere conversion won't help you here. There's no compatibility of any kind between 2D array type and pointer-to-pointer type. Such conversion would make no sense.
If you really really need to do that, you have to introduce an extra intermediate "row index" array, which will bridge the gap between 2D array semantics and pointer-to-pointer semantics
Activity solution[a][b];
Activity *solution_rows[a] = { solution[0], solution[1] /* and so on */ };
Activity **mother = solution_rows;
Now accessing mother[i][j] will give you access to solution[i][j].
The reason you can do this for one-dimensional arrays and not two-dimensional arrays has to do with the way in which the actual array elements are stored in memory. For one-dimensional arrays, all of the elements are stored consecutively, so the expression array[i] is equivalent to the expression *(array + i). As you can see, the array size is not needed to perform an array index operation. However, for two-dimensional arrays, the elements are stored in "row major" order, meaning that all of the elements in the zeroth row are stored first, followed by the elements in the first row, followed by the elements in the second row, etc. Therefore, the expression array[i][j] is equivalent to *(array + (i * ROW_SIZE) + j), where ROW_SIZE is the number of elements in each row. Therefore, the array's row size is needed to perform an array index operation, and casting the array variable to a pointer loses that information.
This is c++! Everything is possible! But a this is c++ so it requires some level of understanding.
To that end let's start with a simple example of 2 1-dimensional arrays: char firstName[4] = { 'J', 'o', 'n', '\0' } and char lastName[4] = { 'M', 'e', 'e', '\0' } Let's look at a possible memory layout here:
+------------+-------+
| Address | Value |
+------------+-------+
| 0x76543210 | 0x4A | <- firstName[0] - 'J'
| 0x76543211 | 0x6F | <- firstName[1] - 'o'
| 0x76543212 | 0x6E | <- firstName[2] - 'n'
| 0x76543213 | 0x00 | <- firstName[3] - '\0'
+------------+-------+
| 0x76543214 | 0x4D | <- lastName[0] - 'M'
| 0x76543215 | 0x65 | <- lastName[1] - 'e'
| 0x76543216 | 0x65 | <- lastName[2] - 'e'
| 0x76543217 | 0x00 | <- lastName[3] - '\0'
+------------+-------+
Given this memory layout if you were to do cout << firstName << ' ' << lastName you'd get:
0x76543210 0x76543214
These arrays are really just a pointer to their first element! This illustrates Array to Pointer Decay, which you can read more about here: http://en.cppreference.com/w/cpp/language/array#Array-to-pointer_decay
Before we move on there's something important here to note, chars take up exactly 1-byte so the address of each subsequent char in the array will simply be the next address. That's leveraged by the Subscript Operator in this way: firstName[1] is equivalent to *(firstName + 1). This is true for chars but is also true for any other type which takes up more than 1-byte. Let's take for example: short siArray = { 1, 2, 3, 4 }, a possible memory layout of siArray would look like:
+------------+--------+
| Address | Value |
+------------+--------+
| 0x76543218 | 0x0001 | <- siArray[0] - 1
| 0x7654321A | 0x0002 | <- siArray[1] - 2
| 0x7654321C | 0x0003 | <- siArray[2] - 3
| 0x7654321E | 0x0004 | <- siArray[3] - 4
+------------+--------+
Even though cout << siArray << ' ' << &(siArray[1]) will output:
0x76543218 0x7654321A
*(siArray + 1) will still index the same element of siArray as siArray[1]. This is because when doing pointer arithmetic c++ considers the type of the address being operated on, thus incrementing a short* will actually increase the address by sizeof(short). You can read more about pointer arithmetic here: http://en.cppreference.com/w/cpp/language/operator_arithmetic
Lastly let's look at how c++ stores 2-dimensional arrays. Given: char name[2][4] = { { 'J', 'o', 'n', '\0' }, { 'M', 'e', 'e', '\0' } } a possible memory layout would be:
+------------+-------+
| Address | Value |
+------------+-------+
| 0x76543220 | 0x4A | <- name[0][0] - 'J'
| 0x76543221 | 0x6F | <- name[0][1] - 'o'
| 0x76543222 | 0x6E | <- name[0][2] - 'n'
| 0x76543223 | 0x00 | <- name[0][3] - '\0'
| 0x76543224 | 0x4D | <- name[1][0] - 'M'
| 0x76543225 | 0x65 | <- name[1][1] - 'e'
| 0x76543226 | 0x65 | <- name[1][2] - 'e'
| 0x76543227 | 0x00 | <- name[1][3] - '\0'
+------------+-------+
Since we know an 1-dimensional array value is really just a pointer, we can see from this memory layout that name[0] is not a pointer, it's just the first character of the first array. Thus name does not contain 2 1-dimensional array pointers, but contains the contents of the 2 arrays. (Incidentally on a 32-bit machine not storing the pointers saves 8-bytes of memory, which is pretty substantial for an 8-byte 2-dimensional array.) Thus trying to treat name as a char** would try to use the characters as a pointer.
Having understood this we really just need to avoid using c++'s pointer arithmetic to find dereference the value. To do that we'll need to work with a char* so that adding 1 is really just adding 1. So for example:
const short si2DArray[2][3] = { { 11, 12, 13 }, { 21, 22, 23 } };
const auto psi2DPointer = reinterpret_cast<const char*>(si2DArray);
for(auto i = 0U; i < size(si2DArray); ++i) {
for(auto j = 0U; j < size(*si2DArray); ++j) {
cout << *reinterpret_cast<const short*>(psi2DPointer + i * sizeof(*si2DArray) + j * sizeof(**si2DArray)) << '\t';
}
cout << endl;
}
Live Example
Note that in this example even though I reference si2DArray thought psi2DPointer I'm still using information from si2DArray to do the indexing, namely:
How many arrays are in the major dimension: size(si2DArray)
How many elements are in the minor dimension: size(*si2DArray)
What is the size in memory of the minor dimension: sizeof(*si2DArray)
What is the element type of the array: sizeof(**si2DArray)
You can thus see that the loss of information from converting from an array to a pointer is substantial. You may be tempted to preserve the element type, thereby also simplifying the pointer arithmetic. It's worthwhile to note that only a conversion to char* is considered defined behavior by reinterpret_cast: http://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing
I want to convert 2D array of objects to pointer-to-pointer. How can I do this?
Why? Is it because an interface expects a pointer to pointers?
If so, you'll need to create a new array that contains those pointers.
Activity solution[a][b];
Activity* solutionPtrs[a];
for (int i = 0; i < a; ++i)
solutionPtrs[a] = solution[a];
Activity** mother = solutionPtrs;
Why can't you just cast a 2D array of T to T**? Well, because they have nothing to do with one another!
You can cast a T[a] to a T* because you get a pointer to the first element of the array.
You can do this with 2D arrays as well, but if you have a T[a][b] then it decays to a (T[b])* because a 2D array is not an array of pointers, it's an array of arrays.
Not sure if you were looking for something like this. You should provide more details about what you want to achieve. They are fundamentally different types. One solution is to below.
For the record, if someone finds it useful:
// define matrix
double A[3][3] = {
{ 1, 2, 3},
{ 4, 5, 6},
{ 7, 8, 9}
};
// allocate memory
double ** A_ptr = (double **) malloc(sizeof (double *) * 3);
for (int i = 0; i < 3; i++)
A_ptr[i] = (double *) malloc(sizeof (double) * 3);
// copy matrix
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
A_ptr[i][j] = A[i][j];
printf(" %f ", A_ptr[i][j]);
}
}
You can't. They are fundamentally different types.