1

im trying to make a function that takes an array as a argument and makes a new array that is 1 element bigger and that make the new arrays next element the first arrays current element (array 1 {1,2,3,4,5} array to would then become {0,1,2,3,4,5} ), i got that part working fine, but then the function must return a pointer to the new array and display that array. ive been playing around with the pointers and i can get it to work with plain int variables but not with this array, it keeps displaying garbage. anyone know what ive done wrong?

#include "stdafx.h"
#include <iostream>

using namespace std;

int *newaray(int[], int);

int main()
{
    int *numbers;
    int i;
    int ar1[] = {1,2,3,4,5};

    numbers = newaray(ar1, 5);

    for (i = 0; i <= 5; i++)
    {
        cout << numbers[i] << endl;
    }
    //cout << numbers << endl;

    system("pause");
    return 0;
}

int *newaray ( int array[],int size)
{
    int ar2[] = {0,0,0,0,0,0};
    int i;
    int *ptr;

    ptr = ar2;

    for ( i = 0; i <= size; i ++) 
    {
        ar2[i + 1] = array[i];
    }

    //for (i = 0; i <= size; i++)
    //{
    //  cout << ar2[i] << endl;
    //}
    return ptr;

}
stev0104
  • 45
  • 1
  • 3
  • 11
  • possible duplicate of [Can a local variable's memory be accessed outside its scope?](http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – chris Apr 15 '14 at 03:43
  • Return a `std::vector`. All the function needs is the vector initialized to have one element and then an `insert` call to add the other, or to initialize it to the end size and a `std::copy` to overwrite all but the first element. – chris Apr 15 '14 at 03:43

6 Answers6

2

You need to use dynamic memory allocation, because otherwise your array goes away when the function stack pops. Of course, remember to delete it after you are done with it, so you do not leak memory.

#include <iostream>
#include <string.h>

using namespace std;

int *newaray(int[], int);

int main()
{
    int *numbers;
    int i;
    int ar1[] = {1,2,3,4,5};

    numbers = newaray(ar1, 5);

    for (i = 0; i < 6; i++)
        cout << numbers[i] << endl;

    // Clean up after ourselves.
    delete[] numbers;

    return 0;
}

int *newaray ( int array[],int size)
{
    // Allocate new memory on the heap to store the return value.
    int *ar2 = new int[size + 1];
    memset(ar2, 0, (size +1)*sizeof(int));

    for (int i = 0; i < size; i++) 
        ar2[i + 1] = array[i];

    return ar2;
}
merlin2011
  • 71,677
  • 44
  • 195
  • 329
2

You have to allocate the array dynamically using new operator.

See the code below.

int *newaray ( int array[], int size)
{
    int i;
    int *ar2=new int[size+1]; // note size+1
    ar2[0]=0;

    for ( i = 0; i < size; i ++) // no equal to operator
    {
        ar2[i + 1] = array[i];
    }

    return ar2;

}

And in main, free the memory allocated for the array:

    delete[] numbers;
    return 0;
}
HelloWorld123456789
  • 5,299
  • 3
  • 23
  • 33
2

It is bad style for your function to return int *. This is because it places onus on the caller to worry about memory management.

It is better to place the array inside a container that manages its own memory. Luckily in Standard C++ there are lots of such containers, the simplest is std::vector which can hold an array of variable size. (There is also std::array, but that only works if the size is known at compile-time).

std::vector<int> new_array( int array[], int size )
{
    std::vector<int> vec( array, array + size );
    vec.insert( vec.begin(), 0 );
    return vec;
}

Then in main:

std::vector<int> numbers = new_array(arr1, 5);

for (i = 0; i < numbers.size(); i++)
    cout << numbers[i] << endl;

This code is almost equivalent "under the hood" to what the other posters suggested, except that in this version you do not have to worry about memory management and its associated problems.

M.M
  • 138,810
  • 21
  • 208
  • 365
1

The array is on the stack and goes out of scope once the function returns. The pointer you are returning is not valid.

In your context (trying to create new arrays), you probably need to dynamically allocate the arrays (and remember to delete them once you are done with them)

John3136
  • 28,809
  • 4
  • 51
  • 69
1

You are returning a pointer to an array that gets deleted when you return from the function. The pointer in main points to deleted memory, hence you see garbage. You need to allocate memory from the heap and return a pointer the memory allocated from the heap.

int *newaray ( int array[],int size)
{
   int* ptr = new int[size+1];
   for ( int i = 0; i <= size; i ++) 
   {
       ptr[i + 1] = array[i];
   }
   return ptr;
}

In main, make sure you deallocate the memory.

numbers = newaray(ar1, 5);

for (i = 0; i <= 5; i++)
{
    cout << numbers[i] << endl;
}
delete [] numbers;
R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

Here is a bonus version that uses some more C++ concepts (requires C++11). IMO this sort of task is better for learning a language than tricky input parsing.

#include <vector>
#include <iostream>

template<typename T, size_t size> 
std::vector<T> new_array(T (&array)[size] )
{
    std::vector<T> vec( array, array + size );
    vec.insert( vec.begin(), T() );
    return vec;
}

int main()
{
    int ar1[] = { 1, 2, 3, 4, 5 };

    auto numbers = new_array(ar1);

    for ( auto num : numbers )
        std::cout << num << std::endl;
}

In this version you can replace int ar1[] with an array of double, or std::string, or any of your classes and everything else works unchanged!

M.M
  • 138,810
  • 21
  • 208
  • 365