returning an int array - c++

I have created the following program which is supposed to return an int array to the main function, which will then display it on the screen.
#include <iostream.h>
int* returnArray(){
int* arr;
arr[0]=1;
arr[1]=2;
arr[2]=3;
return arr;
}
int main(){
int* res = returnArray();
for(int i=0; i<3; i++){
cout<<res[i]<<" ";
}
return 0;
}
And i was expecting it to print
1 2 3
but instead, it prints 3 someNumberWhichLooksLikeAPointer 0
Why is that? what can i do to return an int array from my function? Thank you very much!

You forgot to allocate your array:
int* arr = new int[3];
You also need to return it, and free the memory inside main after you finish with the loop in order to avoid a memory leak:
delete[] res;
Although this approach works, it is not ideal. If you have an option of returning a container, say, std::vector<int> it would be a much better choice.
If you must stay with plain arrays, another solution for filling an array inside an API is to pass it in, along with its size:
void fillArray(int *arr, size_t s){
if (s > 0) arr[0]=1;
if (s > 1) arr[1]=2;
if (s > 2) arr[2]=3;
}
int main(){
int res[3];
fillArray(res, 3);
for(int i=0; i<3; i++){
cout<<res[i]<<" ";
}
return 0;
}

You have tagged the question with C++. You Yous should consider to use the C++ solution: use a vector of int
#include <iostream>
#include <vector>
std::vector<int> returnArray(){
std::vector<int> arr(3);
arr[0]=1;
arr[1]=2;
arr[2]=3;
return arr;
}
int main(){
std::vector<int> res = returnArray();
for(int i=0; i<3; i++){
std::cout<<res[i]<<" ";
}
return 0;
}

Related

Dynamically memory allocation

It is code to reverse the values as they entered.When I am running the following code. It is taking 8 inputs only. After that it is not printing anything.
#include <iostream>
using namespace std;
int main() {
int n;
cin>>n;
int *p = new int(sizeof(int)*n);
int q = n;
for(int i=0;i<n;i++)
{
cin>>*p;
p++;
}
for(int j=0;j<n;j++)
{
cout<<*p<<" ";
p--;
}
return 0;
}
You can also try the following answer.
#include <iostream>
using namespace std;
int main() {
int n;
cin>>n;
int *p = (int *)malloc(sizeof(int)*n);
int q = n;
for(int i=0;i<n;i++)
{
cin>>*p;
p++;
}
for(int j=0;j<n;j++)
{
p--;
cout<<*p<<" ";
}
free(p);
return 0;
}
#include <iostream>
using namespace std;
(Not related to the title, but using namespace std is bad practice that can lead to breakage when switching compilers, for example. Better write the std:: prefix when needed, such as std::cin >>.
int main() {
int n;
cin>>n;
int *p = new int(sizeof(int)*n);
The above is allocating a single int object, whose value is sizeof(int)*n, and p points to that integer. You probably mean:
int *p = (int*)malloc(sizeof(int)*n); // bad style
... at the end:
free(p);
But using malloc in C++ is a bad idea, unless you want to go closer to the operating system for educational purposes.
Slightly better is to use new, which besides allocating the objects also calls their constructors (but nothing is constructed for basic types such as int).
int *p = new int[n]; // so-so style
... at the end:
delete [] p;
The above is not the best practice because it requires manual memory management. Instead, it is recommended to use smart pointers or containers whenever possible:
std::vector<int> p(n);
// continue with the code, just like with the pointers
Or allocate the individual elements only when needed.
std::vector<int> p;
p.reserve(n); // this is a minor optimization in this case
// ...
if (int value; std::cin >> value)
// This is how to add elements:
p.push_back(value);
else
std::cin.clear();
This looks ok:
int q = n;
for(int i=0;i<n;i++)
{
cin>>*p;
p++;
}
But this is broken. When the loop starts, p points after the last element. The following *p dereferences a pointer which goes past the last element:
for(int j=0;j<n;j++)
{
cout<<*p<<" ";
p--;
}
Replacing the order of pointer decrement and dereference avoids the crash:
for(int j=0;j<n;j++)
{
p--;
std::cout << *p << " ";
}
Ok, there many issues here:
int *p = new int(sizeof(int)*n);
This memory allocation is wrong. It allocates n times sizeof(int) bytes, so if int is 4 bytes long it will allocates n * 4 integers.
int q = n;
q variable is never used.
for(int i=0;i<n;i++)
{
cin>>*p;
p++;
}
There is no need for pointer arithmetic here. It would be better to access the array in simple p[i] way.
for(int j=0;j<n;j++)
{
cout<<*p<<" ";
p--;
}
Same here...
return 0;
}
You allocated memory, but never deallocate. This will cause memory leaks.
A better, correct version of the program could be:
#include <iostream>
using namespace std;
int main()
{
int n;
cin >> n;
int * p = new int[n];
for (int i = 0; i < n; ++i)
{
cin >> p[i];
}
for (int i = (n - 1); i >= 0; --i)
{
cout << p[i] << ' ';
}
delete [] p;
return 0;
}

How to stop this memory leak

I am learning pointers in C++ and am working on the new and delete functionality .
I have a local function which allocates memory on the heap but because i am returning the 2d array that i have created , I dont understand how to plug this memory leak, any help would be appreciated
main.cpp
#include<iostream>
#include "integers.h"
using namespace std;
int main()
{
int i[]={1,2,3,4};
int n=sizeof(i)/sizeof(int);
cout<<n<<endl;
printint(genarr(i,n),n);
}
integers.cpp
#include<iostream>
using namespace std;
int** genarr(int* val,int n)
{
int i,j;
int **a=new int*[n];
for(i=0;i<n;i++)
a[i]=new int[n];
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(i==j)
a[i][j]=val[i];
return a; // The variable that will leak but because i am returning it , how do stop it
}
void printint(int** a,int n){
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<a[i][j]<<" ";
}
cout<<endl;
}
return ;
}
integers.h
int** genarr(int*val, int n);
void printint(int **a,int n);
compiled by
g++ main.cpp integers.cpp -o integers
I have heard about smart pointers and am planning to learn about them after this , but for now i want to know if there is way to fix this or should i just go for smart pointers ?
To fix the problem, you need to delete what you new'd.
Change the code in main to:
int **arr = genarr(i,n);
printint(arr,n);
// we're done using arr; now we need to free it
for(int j=0;j<n;j++)
delete[] arr[j];
delete[] arr;
You can also extend integers.cpp and add a delarr function that complements genarr:
void delarr(int **a, int n) {
for (int i = 0; i < n; i++) {
delete[] a[i];
}
delete[] a;
}
Then main becomes simply:
int **arr = genarr(i,n);
printint(arr,n);
delarr(arr,n);
The easiest way to avoid memory leaks in C++ is to avoid explicitly calling delete anywhere. Smart pointers can solve this for you.
In your specific case, you could try something like this (untested):
using Vector = unique_ptr<int[]>;
using Matrix = unique_ptr<Vector[]>;
Matrix genarr(const int* val, int n)
{
Matrix a(new Vector[n]);
for(int i=0;i<n;i++)
a[i].reset(new int[n]);
// ...

Printing array obtained as a return value C++ [duplicate]

This question already has answers here:
Closed 10 years ago.
The following code is printing garbage values. I am passing an array to a function which adds 5 to every element, but when it returns that array's pointer, the main is showing garbage.
I have tried both indexing and pointers there in main but still same results. How can I fix this?
# include <conio.h>
# include <iostream>
using namespace std;
int * add5ToEveryElement(int arr[], int size)
{
int theArray[5];
for(int i=0; i<size; i++)
{
theArray[i] = arr[i] + 5;
cout<<theArray[i]<<endl;
}
return theArray;
}
void main()
{
const int size = 5;
int noArr[size];
for(int i=0; i<size; i++)
{
noArr[i] = i;
}
int *arr = add5ToEveryElement(noArr, size);
cout<<endl;cout<<endl;
for(int i=0; i<size; i++)
{
cout<<arr[i]<<endl;
}
cout<<endl;cout<<endl;cout<<endl;cout<<endl;
for(int i=0; i<size; i++)
{
cout<<*arr<<endl;
*arr++;
}
getch();
}
theArray is a local array in the function add5ToEveryElement() which you are returning to main(). This is undefined behaviour.
Minimally you can change this line:
int theArray[5];
to:
int *theArray = new int[5];
It'll work fine. Don't forget to delete it later in main(). SInce you modify the original pointer, save it:
int *arr = add5ToEveryElement(noArr, size);
int *org = arr;
// Rest of the code
//Finally
delete[] org;
Returning an array from a function is generally considered bad.
Unless you MUST have a "new" array, I would suggest the typical case in C and C++ is to modify the input array. If the CALLING function wants to have two separate arrays, then it can do so by making it's own copy. Alternatively, you could write your code to have two arrays passed into your function, e.g.
void add5ToEveryElement(int arr[], int arr2[], int size)
{
for(int i=0; i<size; i++)
{
arr2[i] = arr[i] + 5;
cout<<theArray[i]<<endl;
}
}
then your main would call with two array arguments, and if you wish to use the same as input and output it will do that too.
Sure, this isn't exactly the answer to your question, but it gives a "better" solution to your problem.
I generally dislike allocation in functions - especially "hidden" allocation (this function says it's adding 5 to every element, not "allocate array with added 5 to each element". Code should never do surprising things, and allocating memory is a little bit of a surprise if you only asked for adding 5 to each element)
this is the perfect code
# include <conio.h>
# include <iostream>
using namespace std;
int * add5ToEveryElement(int arr[], int size)
{
int *theArray = new int[5];
for(int i=0; i<size; i++)
{
theArray[i] = arr[i] + 5;
cout<<theArray[i]<<endl;
}
return theArray;
}
void main()
{
const int size = 5;
int noArr[size];
for(int i=0; i<size; i++)
{
noArr[i] = i;
}
int *arr = add5ToEveryElement(noArr, size);
int *p = arr;
cout<<endl;cout<<endl;
for(int i=0; i<size; i++)
{
cout<<arr[i]<<endl;
}
cout<<endl;cout<<endl;cout<<endl;cout<<endl;
for(int i=0; i<size; i++)
{
cout<<*arr<<endl;
*arr++;
}
getch();
delete[] p;
}

How to pass Dynamic Array by reference C++

I'm having trouble understanding how to pass a dynamic array by reference in C++.
I've recreated the problem in this small isolated code sample:
#include <iostream>
using namespace std;
void defineArray(int*);
int main()
{
int * myArray;
defineArray(myArray);
/** CAUSES SEG FAULT*/
//cout<<(*(myArray)); //desired output is 0
return 0;
}
void defineArray(int*myArray)
{
int sizeOfArray;
cout<<"How big do you want your array:";
cin>>sizeOfArray;
/** Dynamically allocate array with user-specified size*/
myArray=new int [sizeOfArray];
/** Define Values for our array*/
for(int i = 0; i < sizeOfArray; i++)
{
(*(myArray+i))=i;
cout<<(*(myArray+i));
}
}
myArray is passed by value itself, any modification on myArray (such as myArray=new int [sizeOfArray];) has nothing to do with the original variable, myArray in main() is still dangled.
To make it passed by reference, change
void defineArray(int*myArray)
to
void defineArray(int*& myArray)
This solution is hopelessly complicated. You don't need new[], pointers or even a reference parameter. In C++, the concept of "dynamic arrays" is best represented by std::vector, which you can just just use as a return value:
#include <iostream>
#include <vector>
std::vector<int> defineArray();
int main()
{
auto myArray = defineArray();
if (!myArray.empty())
{
std::cout << myArray[0] << "\n";;
}
}
std::vector<int> defineArray()
{
int sizeOfArray;
std::cout << "How big do you want your array:";
std::cin >> sizeOfArray;
std::vector<int> myArray;
for (int i = 0; i < sizeOfArray; i++)
{
myArray.push_back(i);
std::cout<< myArray[i] << "\n";
}
return myArray;
}
push_back will work intelligently enough and not allocate new memory all the time. If this still concerns you, then you can call reserve before adding the elements.

Inputing the Size of a 2-dimentional Array

In my code I input the sizes of both dimensions and then declare a two-dimensional array. My question is, how do I use that array as a function parameter? I know that I need to write the number of columns in the function specification but how do I pass the number of columns?
void gameDisplay(gameCell p[][int &col],int a,int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i][j].getStat()==closed)cout<<"C ";
if(p[i][j].getStat()==secure)cout<<"S ";
if(p[i][j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i][j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i][j].getNum()==0)cout<<"0 ";
else cout<<p[i][j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[][col],row,col);
}
I tried this way but it doesn't work.
Thank you.
In C++, you cannot have variable length arrays. That is, you can't take an input integer and use it as the size of an array, like so:
std::cin >> x;
int array[x];
(This will work in gcc but it is a non-portable extension)
But of course, it is possible to do something similar. The language feature that allows you to have dynamically sized arrays is dynamic allocation with new[]. You can do this:
std::cin >> x;
int* array = new int[x];
But note, array here is not an array type. It is a pointer type. If you want to dynamically allocate a two dimensional array, you have to do something like so:
std::cin >> x >> y;
int** array = new int*[x]; // First allocate an array of pointers
for (int i = 0; i < x; i++) {
array[i] = new int[y]; // Allocate each row of the 2D array
}
But again, this is still not an array type. It is now an int**, or a "pointer to pointer to int". If you want to pass this to a function, you will need the argument of the function to be int**. For example:
void func(int**);
func(array);
That will be fine. However, you almost always need to know the dimensions of the array inside the function. How can you do that? Just pass them as extra arguments!
void func(int**, int, int);
func(array, x, y);
This is of course one way to do it, but it's certainly not the idiomatic C++ way to do it. It has problems with safety, because its very easy to forget to delete everything. You have to manually manage the memory allocation. You will have to do this to avoid a memory leak:
for (int i = 0; i < x; i++) {
delete[] array[i];
}
delete[] array;
So forget everything I just told you. Make use of the standard library containers. You can easily use std::vector and have no concern for passing the dimensions:
void func(std::vector<std::vector<int>>);
std::cin >> x >> y;
std::vector<std::vector<int>> vec(x, std::vector<int>(y));
func(vec);
If you do end up dealing with array types instead of dynamically allocating your arrays, then you can get the dimensions of your array by defining a template function that takes a reference to an array:
template <int N, int M>
void func(int (&array)[N][M]);
The function will be instantiated for all different sizes of array that are passed to it. The template parameters (dimensions of the array) must be known at compile time.
I made a little program:
#include <iostream>
using namespace std;
void fun(int tab[][6], int first)
{}
int main(int argc, char *argv[])
{
int tab[5][6];
fun(tab, 5);
return 0;
}
In function definition you must put size of second index. Number of column is passed as argument.
I'm guessing from Problems with 'int' that you have followed the advices of the validated question and that you are using std::vector
Here is a function that returns the number of columns of an "array" (and 0 if there is a problem).
int num_column(const std::vector<std::vector<int> > & data){
if(data.size() == 0){
std::cout << "There is no row" << std::endl;
return 0;
}
int first_col_size = data[0].size();
for(auto row : data) {
if(row.size() != first_col_size){
std::cout << "All the columns don't have the same size" << std::endl;
return 0;
}
}
return first_col_size;
}
If you're using C-style arrays, you might want to make a reference in the parameter:
int (&array)[2][2]; // reference to 2-dimensional array
is this what you're looking for?
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
example . . .
#include <iostream>
#include <stdio.h>
int* generate2DArray(int rowSize, int colSize);
int random(int min, int max);
int main()
{
using namespace std;
int row, col;
cout << "Enter row, then colums:";
cin >> row >> col;
//fill array and display
int *ptr = generate2DArray(row, col);
for(int i=0; i<row; ++i)
for(int j=0; j<col; ++j)
{
ptr[i,j] = random(-50,50);
printf("[%i][%i]: %i\n", i, j, ptr[i,j]);
}
return 0;
}
int* generate2DArray(int rowSize, int colSize)
{
int* array2D = new int[rowSize, colSize];
return array2D;
}
int random(int min, int max)
{
return (rand() % (max+1)) + min;
}
instead of accessing p[i][j] you should access p[i*b + j] - this is actually what the compiler do for you since int[a][b] is flattened in the memory to an array in size of a*b
Also, you can change the prototype of the function to "void gameDisplay(gameCell p[],int a,int b)"
The fixed code:
void gameDisplay(gameCell p[],int a, int b) {
for(int i=0;i<a;i++) {
for(int j=0;j<b;j++) {
if(p[i*a +j].getStat()==closed)cout<<"C ";
if(p[i*a +j].getStat()==secure)cout<<"S ";
if(p[i*a +j].getBomb()==true&&p[i][j].getStat()==open)cout<<"% ";
if(p[i*a +j].getBomb()==false&&p[i][j].getStat()==open) {
if(p[i*a +j].getNum()==0)cout<<"0 ";
else cout<<p[i*a +j].getNum()<<" ";
}
cout<<endl;
}
}
}
int main() {
int row,col,m;
cout<<"Rows: ";cin>>row;cout<<"Columns: ";cin>>col;
m=row*col;
gameCell p[row][col];
gameConstruct(p[][col],m);
gameDisplay(p[],row,col);
}