What does (int **array;) create? - c++

I want to know what is happening in memory when you declare:
int **array;

If I am not mistaken...
You have a multidimensional array arr[i][j] and
**arr addresses to arr[0][0]
*((*arr)+1) addresses to arr[0][1]
*(*(arr+1)+1) addresses to arr[1][1]
Sample code in C++
#include <iostream>
using namespace std;
int main()
{
int **arr;
arr = new int*[5];
for(int i = 0; i < 5; i++)
arr[i] = new int[5];
arr[0][1] = 1;
cout << *((*arr)+1); // prints 1
cout << arr[0][1] = 1; // prints 1
}

It creates a variable to store a pointer to an int pointer.

The compiler reserves four bytes (on a 32bit system, eight bytes on 64bit) to store a pointer (that would point to another pointer, that would point to an int). No further memory allocation is done, it is left to the programmer to actually set the pointer to point to some other memory location where the int*/array/... is stored.

You're declaring a pointer variable, so you're allocating enough space for one memory address (depends on your platform/compiler/etc.)
The type system will ensure that the only addresses you assign into it contain other memory addresses, and that these addresses represent the actual address of an integer variable.
To use your pointer-to-pointer, you dereference it once (to get the address that actually points to the integer), and then a second time (to get the actual integer).
You can bypass the type system by explicitly casting to something else (e.g., i=&pDouble) but that is not recommended unless you're sure you know what you're doing.
If you have a two-dimensional array, you can think of it conceptually as one single-dimensional array of single-dimensional arrays representing rows. The first level of indirection would be to pick the row, and the other one to pick the cell in the row.

It's a pointer to an int pointer. This is often used to declare a 2D array, in which case each int pointer is an array and the double pointer is an array of arrays.

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++.

Pointers for int and Arrays

Hello i'm a noob in programming, i have a small doubt regarding pointers
#include<iostream>
using namespace std;
int main()
{
int myAge = 16;
int* agePtr = &myAge;
cout << "address of pointer" << agePtr << "Data at memory address" << *agePtr << endl;
int badNums[5] = {4, 13, 14, 24, 34};
int* numArrayPtr = badNums;
cout<< "address" << numArrayPtr << "value" << *numArrayPtr << endl;
numArrayPtr++;
cout<< "address" << numArrayPtr << "value" << *numArrayPtr << endl;
return 0;
}
In the first case while pointing an integer i use &myAge where as in
the second case of incrementing Arrays if i use &badNums the compiler
is returning an error, but if i use badNums its compiling why should
we use badNums instead of &badNums in the second case?
how can I increment the value in integer using pointers?
Arrays implicitly decay to pointers, as per the rules of c++. There are many implicit conversions in c++, this is one of them. When assigning an array to a pointer, it provides you with a pointer to the first element in the array.
Taking the address of an array (&badNums) will yield a pointer to the array, not to the first element. Array pointers are slightly more complicated and encode the size of the array in the type. The correct type for that assignment would be int (*numArrayPtr)[5] = &badNums; where numArrayPtr is a pointer to an array of 5 ints.
To increment a value pointer to by a pointer, you must first dereference that pointer using operator * just like if you wanted to read from or write to that value. It would look like (*numArrayPtr)++;.
In the first case, using &myAge refers to the address of that integer value. The reason why you must use badNums instead of &badNums when doing assignment to the integer pointer is because badNums is already an integer pointer. Arrays implicitly decay into pointers, so using &badNums in that assignment would work if you were doing:
int **numArrayPtr = &badNums;
which is just a pointer to a pointer to the address of badNums. So,
int *numArrayPtr = badNums;
just means that we have a pointer to the address of badNums.
When we have an integer pointer like this, you can increment the value of each integer in the array by doing this:
for (int i = 0; i < 5; i++){
numArrayPtr[i]++;
}
or, we can do the same thing without using array notation:
for (int *i = numArrPtr; i != numArrPtr + 5; i++){
(*numArrPtr)++;
}
I hope that answers your questions fully.
I have a small doubt regarding pointers
Just like i in badnums[i] is an index within array badnums[], a pointer is an index to something stored in memory. Since any variable is stored in memory, you can access the contents of a variable with a pointer to whatever it contains (which is what languages implicitly do when using variables in your code).
The difference is that with pointers you must know the type of what the pointer designates, while an index uses the known type of the indexed elements of the variable it points to... because sooner than later you will iterate the contents of some known variable using a pointer.

Which data type does pointer points to?

I am kind of confused with the pointers.
Say if I have this:
int size;
int bytes;
int numbers;
int *ptr;
ptr = new int[500];
My question is the pointer at first points to any specific variable or just to overall int variables. What if I want a pointer to point only at numbers variable.
I have a tail question if you don't mind. I am trying to allocate dynamic memory to my array, is this valid? :
int numbers[20];
int *ptr;
ptr = new int[size];
Would this give a heap memory to my array?
I am working with an array of very large size and there is no other way to work with it without using heap memory.
P.S: I can't use vector at this point.
int *ptr is an pointer to an int variable. It doesn't matter what variable, as long as it is an int so you could have the following.
int size;
int bytes;
int numbers;
int *ptr;
ptr = &size;
ptr = &bytes;
ptr = &numbers;
I use the & symbol because this gives the actual address of the variable not its value. Pointers can only store the address of a variable.
If you then wanted to use the actual values that the pointer points to, you need to deference it, like so
int number = 5;
int *ptr;
ptr = &number;
cout << *ptr;
//5
As for your second question. Yes that would give you a valid pointer to an array on the heap.
For more information I suggest looking up what an array actually is, since you might be confused why you don't need to use the & symbol when assigning a pointer to an array.
int *ptr is uninitialized, so it actually points to "garbage values" or in this case, random memory addresses. Check out Uninitialized pointers in code
If you want int *ptr to point to the value of numbers, you should first initialize int numbers, because this can cause Undefined behavior if you try to dereference it.
You can assign the ptr equal to numbers by using the Address-of operator &. Then use the dereference operator * to grab the value of ptr.
numbers = 4;
ptr = &numbers;
cout << *ptr << endl;
This will print 4.
int arNumbers[20];
gives you memory from stack and is not dynamic and compiler would take care of releasing the memory.
int *pNumbers = new int[20];
gives you memory from heap and is dynamic and you need to delete it when you are done:
delete[] pNumbers;
if you need 20 numbers, one of them is enough.

Understand how this double becomes an array?

So I'm currently reading and learning a code from the internet (related to artificial neural network) and I found a part of the code that I don't understand why it works.
double* inputNeurons;
double* hiddenNeurons;
double* outputNeurons;
This is how it was declared. Then in this next code, it was changed and used as an array?
inputNeurons = new( double[in + 1] );
for ( int i=0; i < in; i++ ) inputNeurons[i] = 0;
inputNeurons[in] = -1; // 'in' is declared in the function as an int
So, I want to understand why and how it works. Did it become an array of "doubles"? If so, in what way can I also use this? Can this be used for struct or even class?
Every array can be treated as a pointer. But that does not mean every pointer is an array. Do not mix this up!
Assuming we have an array int test[..], the variable name also represents the address where the array is stored in the memory. So you could write
int * p = test;
At that moment my pointer p "becomes" an array, where "becomes" means 'points to an array'. Your example is similar - the only difference is that the memory is allocated dynamically (heap) and not on the stack (as in my example).
So how are the elements accessed?
Let's say, we want to get the first element (index 0).
We could say
int i = test[0];
or we could say
int i = *p;
Now we want to get the element at index 1:
int i = test[1];
Or - by using pointer arithmetics we could write
int i = *(p + 1);
In C++ (and C) pointers support indexing operator [] which basically adjusts the value of the pointer by the amount specified times the size of the type pointed.
So basically
inputNeurons[5] = 0;
is equivalent to
*(inputNeurons+5) = 0
Now this doesn't give you any guarantee about the fact that inputNeurons points to an address which is correctly allocated to store at least 6 double values but syntactically it is correct and well defined.
You are just adjusting an address to point to the i-th element of a given type starting from the specified address.
This means that
double x;
double* px = &x;
px[5] = 0;
Is syntactically correct although it is wrong, since px+5 is an address which points to memory which has not been reserved correctly to hold that value.
The pointer of type double (double* inputNeurons;) just gets assigned to point to the beginning of an dynamically allocated array (new( double[in + 1])) of the same type. It does not become an array.
You can do this with any other pointer and regular array of the same type. As a matter of fact an array is a pointer to specific address (to its beginning, i.e. to the element with index: 0).
When you increment the pointer by + 1, that one means 1 * type_size (i.e 1 * size_of_double)
In your case: inputNeurons points to the address of the first element of the array. If you dereference it: *inputNeurons, you will get the value stored at that address (if inputNeurons was an array, it would be equivalent to: inputNeurons[0] ). To access the next element just increment by one (*inputNeurons + 1).

A doubt about sizeof

I was trying to do something using sizeof operator in c++.
Please refer to the following code snippet.
http://ideone.com//HgGYB
#include <iostream>
using namespace std;
int main()
{
int *pint = new int[5];
int temp = sizeof(*pint);
cout << "Size of the int array is " << temp << endl;
return 0;
}
I was expecting the output as 5*4 = 20. Surprisingly it comes to 4. Any ideas ?
Here is pint is an int*. So,
sizeof(*pint) == sizeof(int)
Compiler doesn't know about new int[5], when it does sizeof(*pint) (because sizeof() is a compile time operator).
[Note: Try the same test with statically declared array, int pint[5]; and will see the expected result.
Additionally, sizeof() returns size_t (which is an unsigned value), so it should be:
size_t temp = sizeof(...);
]
Dynamically sized arrays lose their size information- the size is only the size of one integer, as pint is a pointer to int, and *pint is an integer, not an array type of any size.
There is no way for C++ to know the size of the array.
In your case,
*pint
returns an int, and sizeof(int) is 4 on your machine.
All fine. You ask for the size of an int which will be 4 bytes.
pint is a pointer to int that just happens to point to the beginning of an array. It contains no information about this array.
It is giving you the size of what the pointer points to - the first location in the array.
In the current case sizeof(*pint) is giving the sizeof(int), so its returning 4 . But, even if you will try sizeof(pint), it will return you the size of a pointer. Which will most probably be 4 if yours is a 32 bit machine else it will be 8, if 64 bit machine.
Now you have asked, why it is not returning 4*5 = 20. Since pint points to an integer array. Yes, pint points to an integer array, but its not an array. The difference is :
Array have a fixed size. you can redectare it at all. While pointers can point to any object of any size.
Since sizeof operator is evaluated at compile time, so compiler dont have any way to know at which size of array this pointer is pointing and so cant tell the size of that object and so it always return only the size of pointer. now you can understand, why in case of pointers compiler gives size of the pointer (ie space occupied by pointer in memory), but in case of array it gives full size.