How a double pointer fetch the value from a single poiner - c++

An array is right now pointed by a single pointer. And a double pointer is pointing to the single pointer. I am trying to fetch the value of the array using this double pointer. As far I have only fetched the first index value of the array by the double pointer.
I know that if I dereference (*ptr2) a double pointer then it will give the address where the first pointer is pointed (ptr1) which means the first index address of the array(&array[0]).
#include <iostream>
using namespace std;
int main(){
int array[5]{15,25,35,45,55};
int* ptr1;
int** ptr2;
ptr1 = &array[0];
ptr2 = &ptr1;
In the following for loop, I have tried to print the value of array using pointer ptr1.
for(int i =0; i<5; i++){
cout<<"the value: "<<*(ptr1+i)<<" lives at "<<ptr1+i<<" address\n";
}
cout<<"\n";
In the following for loop I have tried to check *ptr2 is all-time giving me address pointed by ptr1 or not. But I have found that it only works/same for the first index then it is (*ptr2) giving me a different address
for(int j=0; j<5; j++){
cout<<"adress of array: "<<&array[j]<<" , ptr1: "<<(ptr1+j)<<" , val of ptr2: "<<*(ptr2+j)<<endl;
}
cout<<"\n";
return 0;
}
While I have tried to fetch the value from ptr2 by using **ptr2+i using a for loop it continues only for 2 times. First-time correct value which is obvious as I am seeing the address of array[0] and *(ptr2+0) are same. Second-time garbage value and then Segmentation fault (core dumped).
One guess came in my mind that ptr1 and ptr2 both are int type but one is pointing to a variable and another is to a pointer. So maybe there is a memory allocation concept arises from the very beginning which I am skipped.
Is there any way where I can fetch the value of the array using the mentioned structure?

ptr2 is pointing at ptr1. (ptr2+j), when j is not 0, is an address you haven't allocated so dereferencing it (*(ptr2+j)) makes your program have undefined behavior and getting a Segmentation fault is one possible outcome.
You should dereference it first, then index: (*ptr2)[j] or *((*ptr2)+j) if you will.

Your reasoning is close, but you did not apply it well.
I know that if I dereference (*ptr2) a double pointer then it will give the address where the first pointer is pointed (ptr1)
In other words, *ptr2 is a synonym for ptr1. So any place you see ptr1 (after assigning ptr2 = &ptr1) you can substitute in *ptr2. Even better, substitute in (*ptr2) to avoid interference from operators with a higher precedence than de-reference. Let's take an example:
for(int i =0; i<5; i++){
cout<<"the value: "<<*(ptr1+i)<<" lives at "<<ptr1+i<<" address\n";
}
cout<<"\n";
Now do a simple find-and-replace. Replace ptr1 with (*ptr2). Don't try to adjust anything; once you've decided to do this, the process is mindless.
for(int i =0; i<5; i++){
cout<<"the value: "<<*((*ptr2)+i)<<" lives at "<<(*ptr2)+i<<" address\n";
}
cout<<"\n";
This is almost what you tried in your loop, except you used *(ptr2+j) instead of (*ptr2)+i. We can ignore the change from i to j, but those parentheses are significant. You changed the order of operations, which is comparable to using 3(1+4) instead of (3×1)+4. It shouldn't be surprising that 15 does not work where 7 is needed, and similarly adding j before de-referencing does not work where the de-reference needs to be done first.
Note: Since de-reference has a higher precedence than addition, the parentheses around *ptr2 could be dropped from this particular example. That is, *ptr2+i and *(*ptr2+i) would also work.
Note: This question can serve as a demonstration of why it's often wise to avoid pointers-to-pointer.

Related

Segmentary fault with pointer array C++

I get Segmentary fault with this code:
#include <iostream>
using namespace std;
int* arrayCreate(int length){
int *ew[length];
for (int i=0; i<length; i++)
{
*(ew[i])=i;
}
return ew[0];
}
int main(){
int *ptr=arrayCreate(7);
cout << *ptr << endl;
}
And when I tried to change this line
int *ew[length];
into
int *ew = new int[length];
I have error < indirection requires pointer operand ('int' invalid) >
Any one please explain the difference between these two declaration, why I get segmentary fault and how to fix it?
In the first version, you allocate array of pointers on the stack and return an element of that array - which is dead once the function finishes. Accessing this return value means undefined behaviour.
In the second version, you create array of ints (not pointers) on the heap. Thus the syntax error.
What you want is
int* arrayCreate(int length){
int* ew = new int[length];
for (int i=0; i<length; i++)
{
ew[i]=i;
}
return ew;
}
Or better yet, don't use new[], use std::vector, which manages memory for you:
#include <vector>
#include <numeric> //for std::iota
std::vector<int> arrayCreate(int length){
std::vector<int> v (length);
std::iota(v.begin(), v.end(), 0); //you can use your loop as well
return v;
}
int *ew[length];
Problem 1: The size of an array variable must be compile time constant. length is not a compile time constant. Thus, the program is ill-formed.
how to fix it?
If you need an array with dynamic size, you need to allocate dynamically. Simplest solution is to use std::vector.
why I get segmentary fault
Observation: The pointers in ew have indeterminate values. They don't point to any valid object.
*(ew[i])=i;
Problem 2: You indirect through a pointer stored in the array. Since you're indirecting through an invalid pointer, the behaviour of the program is undefined.
Ask yourself: What int object was ew[i] supposed to be pointing to?
how to fix it?
Don't read indeterminate values, and don't indirect through invalid pointers.
int *ew = new int[length];
Here, you create a dynamic array of integers. Array of integers is not an array of pointers. ew is a pointer to an integer. ew is not a pointer to a pointer.
*(ew[i])=i;
Here, you indirect through ew to access ith successor sibling, and then indirect through that sibling. But the first indirection results in an int object and you cannot indirect through an int.
how to fix it?
Don't try to indirect through an int.
Any one please explain the difference between these two declaration
int *ew[length] is an ill-formed and uninitialised array of pointers to int. int* ew is a single pointer to an int, in this case initialised with the address of a first element of a dynamic array of int.
To get memory for your array in C++ you should write:
int *ew = new int[length];
To return the pointer you should write:
return ew;
This means you return pointer to the beginning of array. It should be mentioned that a[i] <=> *(a + i). You can't write *(ew[i]) = i; to assign, but ew[i] = i; will work.
It should also be said that usage of raw pointers is deprecated in modern c++.

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.

C++ pointer arithmetic in a loop and memory management?

I am getting started with C++. I wanted to understand the different
outputs while playing around with this snippet of code.
int main()
{
int i = 3;
int *ptr = &i; //stores address of the i
while(*(ptr)--) //the same as i--
{
cout << *ptr << endl;
}
}
When I run this code I understand that the deferenced value
of ptr, which is "i", gets 1 subtracted from it and the loop exits
when "i" equals 0. But when I use while(*ptr--) instead of while(*(ptr)--) I get a list of random integers which eventually go down to 0 and the loop breaks.
To my understanding when I use *ptr-- I am subtracting a byte(size of one int) from the initial address of &i(*ptr) with each loop. But why does the program terminate eventually? No matter what the value of "i" is, the program prints 23 random numbers with the last one being 0 and the loop exits. Should I not get an overflow error since the program runs out of memory?
However, when I use while(ptr--) the program does go into an infinite loop.
What exactly is happening?
Thank you very much.
(ptr) is the same as ptr, thus (ptr)-- is the same as ptr--.
*ptr-- IS NOT the same as i-- !
You are applying operator-- to the right side of the pointer. The suffix/postfix operator-- has a higher precedence than operator*. So, *ptr-- is the same as *(ptr--), not (*ptr)-- like you are expecting.
IOW, ptr-- gets evaluated first, which returns a copy of the current pointer and then decrements the pointer, and then you are dereferencing the copied pointer to retrieve the value that was previously being pointing at.
That is why you are seeing garbage - you are decrementing the pointer into memory that does not belong to you.
To simply decrement the int and not the pointer, use (*ptr)-- instead. IOW, dereference the pointer first, then decrement the value being pointed at, eg:
int main()
{
int i = 3;
int *ptr = &i; //stores address of the i
while((*ptr)--) //the same as i--
{
cout << *ptr << endl;
}
}
Live demo
Parenthesis and operator precedence matter!

Why it doesn't yield memory-addresses when looping through a pointer?

When we print ptr, it gives a memory address, but when we loop through it, we get array elements. What's causing the difference & why so?
int main()
{
string texts[] = { "one", "two", "three" };
string* ptr = texts;
for (int i = 0; i < 3; i++) {
cout << ptr[i];
}
_getch();
return 0;
}
When we print ptr, it gives a memory address, but when we loop through it, we get array elements.
ptr is a pointer so when you print it you get a memory address.
Note ptr[i] is the same as *(ptr + i). So when you loop using array syntax ptr[i] you are dereferencing it and so you get the data itself.
The type of ptr is string* - a pointer to a string. The type of ptr[i] is string.
cout is a global instance of class ostream. This class defines an insertion operator, i.e. operator<<() for string objects which specifically prints the contents of the string. Therefore cout << ptr[i] prints the text. On the other hand, ostream does not specifically define an insertion operator for pointers to strings. So the closest matching definition is operator<<(void*) - an insertion operator for pointers in general. This just prints the address.
ptr[i] is the same as *(ptr + i).
a container object like a string or an array is a pointer to the first element in that container. the [] operator access a certain object based on the starting location like #artm said. this question is the result of a lack of understanding how variable memory allocation works. look into that for a more complete answer.
When you write string* ptr= texts; the starting address of the array is stored in the pointer memory i.e. the pointer now points to the starting address of the array. So, whenever you'll print ptr, an address will be printed.
But when you loop through it i.e. ptr[I] it's evaluated as *(ptr+i). * is the dereferencing operator which means it gives the value stored at the address given to it. Therefore, *(ptr+i) becomes the_value_at(location saved in ptr + i more units). Which is why you get array values.

Copying Int Array Stored at Void Pointer to Int Array

In the below loop, I am attempting to copy data stored at the address of voidPtr. The data here is known to be an integer array of length count. I've read that casting this array to an int and then performing the copy (as shown below) should work.
int intArr[count];
for (int i = 0; i<count; i++){
intArr[i] = ((int*) voidPtr)[i];
}
However, when I attempt to print the array int by int, I am receiving a seg-fault.
for (int i = 0; i<count; i++){
printf("%d ", intArr[i]);
}
Any ideas?
You are doing wrong stuff, and when compiler warned you, you just shut it up with the cast. No you've shoot yourself in the foot, and who is to blame? :)
What you did was to say that voidPtr now becomes an int*, and please access it's element i. This can't be correct. Most likely, on your system void* is not the same as int*, so with this cast you will be accessing incorrect elements. Also, your void* does not seem to point to the big enough location - this is what causing the crash.
Do not use void* in C++, do not cast.