How can I return a pointer to an array in C++? - 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;

Related

Revisited: difference between static array and dynamic array in C++?

I'm a beginner for C++ and I saw the post here. However, it is very unclear for me what is the benefit of dynamic array.
One advantage is that one can change the length of a dynamic array, here is the code
int *p = new int[10];
// when run out of the memory, we can resize
int *temp = new int[20];
copy(p, temp); // copy every element from p to temp
delete[] p; // delete the old array
p = temp;
temp = nullptr;
Above is for dynamic allocation, it says the array will be on the heap, and need to manually delete it. However, why not use the static array as follow
int array1[10];
int *p = array1;
// when run out of the memory, we can resize
int array2[20];
copy(array1, array2); // copy every elements from array1 to array2;
p = array2;
In this code, we don't need to delete the array1 since it is on the stack area. Here are my question:
what is the benefit of the dynamic array? It seems for me, resizing is not a big issue. People always say the size of static array are fixed, the size of dynamic array is not fixed. Why the size of dynamic array is not fixed. for example, int p=new int[10], the size of p is fixed.
Thanks a lot.
int array1[10];
int *p = array1;
// when run out of the memory, we can resize
int array2[20];
copy(array1, array2); // copy every elements from array1 to array2;
p = array2;
In whichever function, or inner scope, array1 and array2 get declared these arrays get automatically destroyed when the function or inner scope returns. Full stop.
This is why this is called "automatic scope". The fact that there may be a pointer to one of the arrays is immaterial. The array will be gone and any attempt to dereference that pointer will result in demons flying out of your nose.
So if you had any grand designs to continue using this array, in some form or fashion, after returning from the function where they get declared, too bad. It's not going to happen.
On the other hand, after newing something, as long as you properly track the pointer to the newed object(s) they can be used anywhere else, until they get deleted. This function, another function, anywhere. Even a different execution thread.
Having said all of that, you should not be using new or delete either. You should be using C++ library's containers which will correctly handle all memory allocation, deallocation, and copying, for you. In this case, you are simply reinventing what std::vector already does for you, and it will actually do it, in some ways, far more efficient than you can do easily on your own. You just call resize(), and, presto, your vector is bigger or smaller, as the case may be. And, in all other respects the vector will be indistinguishable from your array. It will be very hard to tell the difference.
So, use C++ library's containers. They are your friends. They want you to do memory allocation correctly, on your behalf. Modern C++ code rarely uses new or delete, any more. It's important to understand how it works, but 99% of the time you don't really need it.
Doing your own dynamic array with new int[20] and delete[] etc, is no doubt good for learning how it all works.
In real C++ programs you would use std::vector. Maybe like this:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<std::string> lines;
std::string line;
while (std::getline(std::cin, line)) {
lines.push_back(line);
}
std::cout << "Read " << lines.size() << " lines of input\n";
}
The reason you would use dynamic allocation is so your program can handle any number of lines of any line length. This program can read four lines or 400,000. The std::vector is dynamic. So is std::string.
I have write a code on static and dynamics array, hope this will help.
#include<iostream>
using namespace std;
int main (){
//creating the static array .. rember the syntax of it.
int array[4]= {1,2,3,4}; // size is fixed and can not be changeable at run time.
cout<<"Static Array."<<endl;
cout<<"Printing using index."<<endl;
for(int x=0;x<4;x++){
cout<<"\t"<<array[x];
}
cout<<endl;
cout<<"Printing using pointer."<<endl;
int*ptr= array;
for(int x=0;x<4;x++){
cout<<"\t"<<*ptr++;
}
//delete [] array ;// error, because we can not free the size from stack
// array[6]= {1,2,3,4,5,6}; //Error: We can not change the size of static array if it already defined.
// we can not change the size of the static aray at run time.
cout<<endl;
cout<<"\n\nDynamic Array."<<endl;
int n=4;
//Creating a dynamic Array, remember the systex of it.
int *array2 = new int [n]; // size is not fixed and changeable at run time.
array2[0]= 1;
array2[1]= 2;
array2[2]= 3;
array2[3]= 4;
cout<<endl;
cout<<"Printing using index."<<endl;
for(int x=0;x<4;x++){
cout<<"\t"<<array2[x];
}
cout<<endl;
cout<<"Printing using pointer."<<endl;
int*ptr2= array2;
for(int x=0;x<4;x++){
cout<<"\t"<<*ptr2++;
}
cout<<endl<<endl<<endl;
delete array2; //Size is remove at runtime
cout<<"Chnaging the size of dynamic array at runtime... :)";
// Changing the size of the array to 10.. at runtime
array2 = new int [10]; // Array size is now change to 10 at runtime
array2[0]= 1;
array2[1]= 2;
array2[2]= 3;
array2[3]= 4;
array2[4]= 5;
array2[5]= 6;
array2[6]= 7;
array2[7]= 8;
cout<<endl;
cout<<"Printing using index."<<endl;
for(int x=0;x<7;x++){
cout<<"\t"<<array2[x];
}
// free the memory/ heap
delete [] array2;
return 0;
}
Output

Passing multidimensional arrays to function_111

do_something(int array[][])
{
}
int main()
{
int array_length;
cin>> array_length;
int array[array_length][array_length];
for()
{
"putting elements of array"
}
}
I have seen people putting some const int so they can pass array to the function. Question is how do I pass a multidimensional array to the function if I don't know its size until it is entered.
int array[array_length][array_length];
This line will not compile. Unlike some other languages (Java, possibly), allocating an array of dynamic size is different than one of constant size. The [] notation will create a constant-size array, which will not work your attempt to pass it array_length. To allocate this array dynamically, use
int **array = new int*[array_length];
The you'll need to iterate through array and allocate each sub-array to the correct size with
array[i] = new int[array_length];
After this, you'll need to reference array_length when iterating through array, as it is your only indication as to the size of the array.

C++ Pointer and 2d array outputting

I'm new to C++ and still really confused about how 2d arrays work with pointers. If I have this (in example format):
int* anarray = anarrayfiller();
for (int a=0;a<10;a++) {
for (int b=0;b<10;b++) {
cout<<(char)anarray[a][b]; //Here's the error mentioned below
}
cout<<"\n";
}
//Later, outside main
int* anarrayfiller() {
int anarray[10][10];
//Populated here
return &anarray;
}
This produces an error under b in the cout<< line:
"Expression must have pointer-to-object type"
I would just check how to search through 2d arrays, and I found this:
A pointer to 2d array
Which suggests that actually this pointer points to the array of ints inside anarray[0], and if that's the case, I must be missing something in terms of returning pointers - wouldn't I then have to return a pointer to a 2d array of pointers that each points to a specific int from anarray? I'm pretty confused here. How do pointers work with 2d arrays?
You have a few errors here:
You return a pointer to a local variable. After the function returns the stack area previously occupied by that variable no longer exist, or is used by the next function.
You return a pointer to an integer, while you have a two-dimensional array. The closest would be a pointer-to-pointer.
You access thing single-pointer as though it was a double-pointer (pointer-to-pointer or pointer-to-array or array-or-arrays), but it's not. That's the reason you get errors at the pointed to line.
But you can't use pointer to pointer, as the memory layout of an array-of-arrays (a two-dimensional array) is different from a pointer-to-pointer. See e.g. this old answer of mine for an explanation of why.
This can be solved most easily by creating the array dynamically on the heap, as a pointer-to-pointer:
int **anarrayfiller()
{
int **anarray = malloc(sizeof(int *) * 10);
for (int i = 0; i < 10; ++i)
{
anarray[i] = malloc(sizeof(int) * 10);
/* Populate here */
}
return anarray;
}
As you tagged your question as C++, you should actually avoid plain arrays or pointers in favor of either std::vector (if you need to add dynamically) or std::array (if you have a fixed compile-time size):
std::array<std::array<int, 10>, 10> anarrayfiller()
{
std::array<std::array<int, 10>, 10> anarray;
// Populate arrays
return anarray;
}

returning a 2D array in c++ using typecasting

int** function()
{
int M[2][2] = {{1,2},{3,4}};
return (int **)M; //is this valid?
}
void anotherFn()
{
int **p = new int*[2];
for(int i = 0; i<2; i++) {
p[i] = new int[2];
}
p = function();
cout << p[0][0];
}
The above code compiled but gave runtime error. So, can I return a 2D array only if it was declared as double pointer or is there some way I can return an array as a 2D pointer?
You are representing a 2D array as a pointer to pointer to int. That is a bad idea. A better idea is to use a std::vector<std::vector<int>>. Better yet would be to use a dedicated class. But the point is that once you get rid of pointers you can return the value without any problem:
matrix_2d function() {
matrix_2d M = {{1, 2}, {3, 4}};
return M;
}
This works quite well for an appropriate definition of matrix_2d (see above).
Your code makes this whole process much more complicated by using pointers, and accesses invalid memory. In particular, you are allocating memory in your main function, but then you are discarding the pointer to that memory by reassigning it with the result of function(): inside function you aren’t using the previously-allocated memory, you are using stack-allocated memory and returning a pointer to that. Once the function exits, that stack-allocated memory is gone.
To return a 2D array, make sure you dynamically allocate it, then return the pointer. The problem with your code is that you are returning a pointer to a local variable, which will cause problems.
Basically, you'll want to do something like this (skeleton):
int** function()
{
int** M;
// Allocate M here
return M;
}

What is ** in C++

I am currently reading some C++ source code, and I came across this:
double **out;
// ... lots of code here
// allocate memory for out
out = new double*[num];
Not entirely sure what it does, or what it means. Is it a pointer... to another pointer?
There is also the following:
double ***weight;
// allocate memory for weight
weight = new double**[numl];
I am quite confused :P, any help is appreciated.
new double*[num] is an array of double pointers i.e. each element of the array is a double*. You can allocate memory for each element using out[i] = new double; Similarly weight is an array of double**. You can allocate the memory for each weight element using new double*[num] (if it is supposed to be an array of double*)
It's a pointer to pointer to double. Or array of pointers to double. Or if every pointer itself allocates array it might be a matrix.
out = new double*[num]; // array of pointers
Now it depents if out[0] is allocated like this:
out[0] = new double; // one double
or like this:
out[0] = new double[num]; // now you've got a matrix
Actually, writing
double*[] out;
is in C/C++ equal to
double** out;
and it means an array of pointers to double. Or a pointer to pointers of double. Because an array is nothing more than just a pointer. So this is in essence a two-dimensional array.
You could as well write
double[][] out;
And likewise, adding another pointer level, will add another dimension to your array.
So
double ***weight;
is actually a pointer to a three-dimensional array.
Basically both of your code fragments allocate array of pointers. For allocation it does not matters to what. Correct declaration is needed only for type checks. Square bracjets should be read separately and means only it is array.
Consider following code as quick example:
#include <stdio.h>
int main()
{
unsigned num = 10;
double **p1, ***p2;
p1 = new double*[num];
p2 = new double**[num];
printf("%d\n", sizeof(p1));
printf("%d\n", sizeof(p2));
delete [] p1;
delete [] p2;
return 0;
}
Yes, both are just pointers. And memory allocated is sizeof(double*) * num.