How to access the array from the pointer? - c++

I am trying to understand how pointers work but I do not know how a pointer to only the first element can be used to access all the array
int myArray[10];
for(int i=0; i<10; i++)
{
myArray[i] = 11*i;
}
int *p;
p = myArray;
//Now how do I access the complete array using the variable p
cout<<*p; //This only prints the first value, how to print all the values

You have to use while or for.
int i = 0;
while (i < 10)
{
cout << p[i];
i += 1;
}
Pointers and arrays are working in the same way. An array is nothing else than a pointer to the first element you allocated.

If you for example want to access pos 5, you can just write:
...
int *p;
p = myArray;
cout << p[5];
Since the compiler know that p is a pointer to an int, it will add the size of an int for each step (4 bytes in this case).
As long as you don't use pointers to void, the compiler does this for you.
You still have to keep track of the length of the array so you do not exceeds it since a pointer don't do that.

except for thr declaration, arrays and pointers con be used using the same syntax
(They are different in memory, meaning they still need to be treated differently)

Use like this,
int *p;
p = myArray;
for(int i=0;i<10;i++)
{
cout<<*(p+i);
}

The first element points to the first memory location of the elements in the array. So this:
myArray[0];
and
myArray;
point to the same location. You can use indexes on the pointer, just like you did to fill the array. So this:
int *p = myArray;
cout << p[0];
cout << p[1];
would access your other elements. You can use a for loop to access all the elements in the array, just like you did to populate it in the first place.

You can think of the name of an array as a pointer to its first element.
So, the line p = myArray; is simply copying the address of the first element of the array myArray into p.
Now the line cout<<*p; is obviously displaying the value of what's pointed by p, which is the first element of your array.
To display all the elements, you can simply use a for loop like you did before.

Related

How to create an array of pointers without using vector

I saw that an array of pointers can be created using vector, however, I don't want that. Is the example below a way to create a pointer to int array?
#include <iostream>
using namespace std;
int main() {
int* arr[4];
for (int i=0; i<4; ++i) {
cout<<endl<<arr[i];
}
}
This makes a pointer to int array and it displays the memory address of each index in the array. Now I have few questions. Is it a proper way to create a pointer to int array without a vector? Also, if I want to initialize a value inside each memory address in the given example, how is it done? And lastly why is &arr equal to arr?
While &arr and just plain arr may both give you the same address, they are both very different.
With &arr you get a pointer to the array, and the type of it is (in your case) int* (*)[4].
When you use arr it decays to a pointer to the first element and the type is (again, in your case) int**.
Same address, but different types.
As for the array itself, it's defined fine, you have an array of four pointers to int. However, you do not initialize the contents of the array, which means that the contents is indeterminate, and using those pointers in any way (even just printing them) leads to undefined behavior.
Your proposed way doesn't make pointer to int array. Instead of that it makes a pointer to pointer to an int array. Usually the name of any array represent a pointer to it self. Or &arr[0] also represent it.
So I hope that you got the answer for why &arr equal arr.
Creating a pointer to int array
int arr[4];
int* p = arr; //pointer to int array
Initializing each element in array
(1) Using pointer arithmetic
int size = 4;
int* p = arr;
for (int i = 0; i < size; i++)
{
*p = i; // assigning each element i
p++; //pointing to next element
}
(2) Using operator []
int size = 4;
for (int i = 0; i < size; i++)
{
arr[i] = i; // assigning each element i
}
&arr gives you the address of array which starts with base address ie address of first element.
arr gives the address of first element.
hence u get same result for both

The correct way to initialize a dynamic pointer to a multidimensional array? [duplicate]

This question already has an answer here:
How to properly work with dynamically-allocated multi-dimensional arrays in C++ [duplicate]
(1 answer)
Closed 7 years ago.
I've been having bad luck with with dynamic pointers when I range them to 2 dimensions and higher. For example I want a pointer to a 2D array. I know that:
int A[3][4];
int (*P)[4] = A;
Is completely legit (even if I don't completely understand why). Taking into consideration that:
int *P = new int[4];
works, I imagined that:
int **P = new int[5][7];
Would also work, but it's not. This code states the error:
Error: A value of type "(*)[7]" cannot be used to initialize an entity of
type "int **"
By seeing this the new part becomes a pointer to an array of 7 integers I made:
int (*P)[4] = new int[7][4];
And this does work but it's not what I want to accomplish. By doing it like that I'm limited to at least using a constant value for any subsequent dimension, but I want it to be fully defined at run time and therefore "dynamic".
How could I go and make this multidimensional pointer work??
Let's start with some basic examples.
When you say int *P = new int[4];
new int[4]; calls operator new function()
allocates a memory for 4 integers.
returns a reference to this memory.
to bind this reference, you need to have same type of pointer as that of return reference so you do
int *P = new int[4]; // As you created an array of integer
// you should assign it to a pointer-to-integer
For a multi-idimensional array, you need to allocate an array of pointers, then fill that array with pointers to arrays, like this:
int **p;
p = new int*[5]; // dynamic `array (size 5) of pointers to int`
for (int i = 0; i < 5; ++i) {
p[i] = new int[10];
// each i-th pointer is now pointing to dynamic array (size 10)
// of actual int values
}
Here is what it looks like:
To free the memory
For one dimensional array,
// need to use the delete[] operator because we used the new[] operator
delete[] p; //free memory pointed by p;`
For 2d Array,
// need to use the delete[] operator because we used the new[] operator
for(int i = 0; i < 5; ++i){
delete[] p[i];//deletes an inner array of integer;
}
delete[] p; //delete pointer holding array of pointers;
Avoid memory leakage and dangling pointers!
You want something like:
int **P = new int*[7];
p[0] = new int[5];
p[1] = new int[5];
...
Another approach would be to use a 1D array as an 2D array. This way you only have to allocate the memory once (one continous block);
int *array;
size_t row=5,col=5;
array = (int*)malloc(row*col*sizeof(int)) //or new int[row*col]
This would result in the same as "int array[5][5]".
to access the fields you just do:
array[1 //the row you want
* col //the number of columns
+2//the column you want
] = 4;
This is equal to:
array[1][2];
This performs bounds checking on some debug compilers, uses dynamic size and deletes itself automatically. The only gotcha is x and y are the opposite way round.
std::vector<std::vector<int>> array2d(y_size, std::vector<int>(x_size));
for (int y = 0; y < y_size; y++)
{
for (int x = 0; x < x_size; y++)
{
array2d[y][x] = 0;
}
}

How can I return a pointer to an array in C++?

Here is my simple code
arrayfunc() should store some numbers in an array, and return the pointer of this array
to main function where the content of the array would be printed
What is the problem with my code?
It only returns the pointer to the first element of the array
Any help will be appreciated.
Thanks in advance.
#include <iostream>
using namespace std;
//The definition of the function should remain the same
int* arrayfunc()
{
int *array[10];
array[0] =new int;
array[1] =new int;
array[2] =new int;
array[3] =new int;
*array[0]=10;
*array[1]=11;
*array[2]=12;
*array[3]=13;
return *array;
}
int main()
{
for(int i=0;i<4;i++)
cout<<*(arrayfunc()+i)<<endl;
return 0;
}
(1) You should allocate your array with new if you want to return it: int* array = new int[10]; [assuming here you want array of ints and not array of int*'s]
(2) to return the pointer to the first element in the array, use return array and not return *array
(3) your array is array of pointers, and not array of ints.
Your array is allocated on stack, so as soon as the function returns, it's freed. So you want to return a pointer to a dead memory.
But you are not doing that, you are just returning the valid (copy of) value of the 0th array item.
So, what you have to do:
The best idea would be to switch to stl containers. You should be using std::vector or something like that.
If you stick to the idea of manual memory management, you have to allocate the array on heap, return it from the function, and perhaps deallocate it in the caller.
Edit:
basically you want the following:
using namespace std;
vector<int> arrayfunc()
{
vector<int> v;
v.push_back(10);
...
return v;
}
...
vector<int> result = arrayfunc();
cout << result[0] << ...
This would be the right C++ way.
(Nitpicking:) You don't need to care about copying the vector, because of the RVO used by all modern C++ compilers.
Allocating an array on heap should be simple, too:
int* array = new int[4];
array[0] = 10;
...
return array;
...
int* array = arrayfunc();
...
delete[] array;
But I would strongly advise to take the former approach (with vector).
This codes seems wrong to me in several levels.
Never return an internal variable of a function. The variable array is only defined in the function, so it should never be returned outside.
Why do you allocate each int by itself with new? I would allocate the entire array at once. If you know the array length and it's constant, consider having it defined statically.
http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx
Just try return array; instead of return *array;

allocation of a pointers to fixed size arrays

I have 2 doubts regarding basics of pointers usage.
With the following code
int (*p_b)[10];
p_b = new int[3][10];
// ..do my stuff
delete [] p_b
p_b is pointing to an array of 3 elements, each having fixed-size length of 10 int.
Q1:
How to declare p_b if I want that each element be a pointer to a fixed array size?
Basically I want the following
p_b[0] = pointer to a fixed-array size of 10
p_b[1] = pointer to a fixed-array size of 10
// ... and so on
I was thinking to int (** p_b)[10] but then I don't know how to use new to allocate it? I would like to avoid falling back to more general int** p_b
Q2:
Is per my original code sample above, how to call new so that p_b points to a unique fixed-size array of 10 int other than calling p_b = new int[1][10] ? To free memory I have to call delete[] while I cannot find an expression where I can call only simply delete.
p_b is pointing to an array of 3 elements, each having fixed-size length of 10 int.
How to declare p_b if I want that each element be a pointer to a fixed array size?
Does your first sentence not completely cover that question?
Is per my original code sample above, how to call new so that p_b points to a unique fixed-size array of 10 int other than calling p_b = new int[1][10]? To free memory I have to call delete[] while I cannot find an expression where I can call only simply delete.
I completely do not understand why this is a problem, but you could do it by wrapping your array inside another type... say std::array, boost::array or std::vector.
First of all, if your new expression has square brackets (new somtype[somesize]), your delete has to have square brackets as well (delete [] your_pointer).
Second, right now you've defined p_b to be a single pointer to some data. If what you really want is an array of pointers, then you need to define it as an array. Since you apparently want three independent arrays, you'll have to allocate each of them separately. It's probably easiest if you start with a typedef:
typedef int *p_int;
p_int p_b[3];
Then you'll allocate your three arrays:
for (int i=0; i<3; i++)
p_b[i] = new int[10];
To delete those, you'll need to delete each one separately:
for (int i=0; i<3; i++)
delete [] p_b[i];
I definitely agree with #Tomalak that you should almost never mess with things like this yourself though. It's not clear what you really want to accomplish, but it's still pretty easy to guess that chances are quite good that a standard container is likely to be a simpler, cleaner way to do it anyway.
Here's an example of how to implement Q1:
int main()
{
typedef int foo[10];
foo* f = new foo[3];
f[0][5] = 5;
f[2][7] = 10;
delete [] f;
}
As for Q2, the only way to delete memory allocated with new[] is with delete[]. If you personally don't want to write delete [], you can use a vector or another STL container. Really, unless this is some hardcore uber-optimisation, you should be using vectors anyway. Never manage memory manually unless you are absolutely forced to.
To use a raw pointer to manage a 2-d array you must first create a pointer to a pointer to array element type that will point to each row of the array. Next, each row pointer must be assigned to the actual array elements for that row.
int main()
{
int **p;
// declare an array of 3 pointers
p = new int*[3];
// declare an array of 10 ints pointed to by each pointer
for( int i = 0; i < 3; ++i ) {
p[i] = new int[10];
}
// use array as p[i][j]
// delete each array of ints
for( int i = 0; i < 3; ++i ) {
delete[] p[i];
}
// delete array of pointers
delete[] p;
}
A far easier solution is to use std::array. If your compiler does not provide that class you can use std::vector also.
std::array<std::array<int,10>,3> myArr;
myArr[0][0] = 1;
For Q1, I think you want
int (*p[3])[10];
Try cdecl when you're unsure.
Your other question seems to be well answered by other answers.
regards,
Yati Sagade
Actually, nobody posted an answer to your exact question, yet.
Instead of
int (*p_arr)[10] = new int[3][10];
// use, then don't forget to delete[]
delete[] p_arr;
I suggest using
std::vector<std::array<int, 10>> vec_of_arr(3);
or if you don't need to move it around and don't need runtime length:
std::array<std::array<int, 10>, 3> arr_of_arr;
Q1
How to declare p_b if I want that each element be a pointer to a fixed array size?
int(**pp_arr)[10] = new std::add_pointer_t<int[10]>[3];
for (int i = 0; i < 3; ++i)
pp_arr[i] = new int[1][10];
// use, then don't forget to delete[]
for (int i = 0; i < 3; ++i)
delete[] pp_arr[i];
delete[] pp_arr;
The modern variant of that code is
std::vector<std::unique_ptr<std::array<int, 10>>> vec_of_p_arr(3);
for (auto& p_arr : vec_of_p_arr)
p_arr = std::make_unique<std::array<int, 10>>();
or if you don't need to move it around and don't need runtime length:
std::array<std::unique_ptr<std::array<int, 10>>, 3> arr_of_p_arr;
for (auto& p_arr : arr_of_p_arr)
p_arr = std::make_unique<std::array<int, 10>>();
Q2
Is per my original code sample above, how to call new so that p_b points to a unique fixed-size array of 10 int other than calling p_b = new int[1][10]?
Not without wrapping the array into another type.
std::array<int, 10>* p_arr = new std::array<int, 10>;
// use, then don't forget to delete
delete p_arr;
You can replace std::array<int, 10> with your favourite array-wrapping type, but you cannot replace it with a fixed-size array alias. The modern variant of that code is:
auto p_arr = std::make_unique<std::array<int, 10>>();

How do I pass a reference to an array, whose size is only known at run-time, as a function parameter?

I have an array that is being dynamically created based on user input, and I need to pass that array to a function where it will be manipulated and the results passed back out to the original array. When I try to use
void MyFunction(int (&MyArray)[])
my compiler complains that it doesn't know how big the array is.
You can't. You could use a std::vector though.
You can give a pointer to the first element of the array + a second parameter holding the size of the array.
If it's just an array, why not pass the array itself and its size as a second parameter? (by passing the array as an int* or int[], same thing as far as C++ is concerned).
As the value of the variable containing your array is only the pointer to the first element of your array, you don't end up killing your runtime by copying the contents of the array, but just a pointer which is as small as you can get in this case.
void MyFunction( int MyArray[], int size ) { /* edit the array */ }
int main() {
// read nrElements
// ...
// create the array
int *a = new int[nrElements];
// populate it with data
// ...
// and then
MyFunction(a, nrElements);
}
You should use a std::vector only if you want to resize the array in your function (e.g. add new elements to it), but otherwise you can just stick to this approach because it's faster.
Btw, the only case you would need a reference to an array is if you want to change the value of the variable you pass in when you call the function, as in, make it point to a different array. Like in:
void createMyArray(int* &array, int nrElements) {
array = new int[nrElements];
for (int i = 0; i < nrElements; ++i) {
array[i] = 0;
}
}
int *a = (int []) {1, 2, 3};
std::cout << a[0] << std::endl; // prints 1
createMyArray(a, 10);
// now a points to the first element of a 10-element array
std::cout << a[0] << std::endl; // prints 0
But you said the array is already created before providing it to the function, there's no point in using references.