Sunday, June 7, 2015

Pass an array to a function when you're allowed to pass only one parameter?

A colleague asked me this, and from my experience, if you pass an array to a function, there's no way for the function to know the array size because it does not know at which point of memory the array ends. So the only way seemed to be to do this:

#include<iostream>

void func(int arr[], int s)
{
    for(int i=0; i<s; ++i)
    {
        std::cout<<arr[i]<<"\n";
    }
}

int main()
{
    int a[10] = {1,2,3,4,5,6,7,8,9,0};
    func(a, 10);
}

You'd ask then how does the compiler know where an array ends when you create:
int* myArray = new myArray[10];

and then delete it with:
delete[] myArray;

Apparently, when the memory is allocated with new myArray[10], the compiler will allocate space to store the size of the array + memory to store the array itself. What is returned, is the position where the array begins.
So when it's time to delete, the compiler searches for the array size in array position - 1. This is one way to implement it.


So for ordinary arrays being passed as parameters to a function, one way is to create an array of size 11 if you actually wanted to create an array of size 10. Then use the first cell to store the array size.

#include<iostream>

void func(int arr[])
{
    int s = arr[0];
    for(int i=1; i<s+1; ++i)
    {
        std::cout<<arr[i]<<"\n";
    }
}

int main()
{
    int a[11] = {10, 1,2,3,4,5,6,7,8,9,0};
    func(a);
}


Yet another way I recently found out, is to use a template.

#include<iostream>

template <typename T, int s>
void func(T (&a) [s])
{
    for (int i = 0; i < s; ++i)
    {
        std::cout<< a[i] << "\n";
    }
}

int main()
{
    int x[10] = {1,2,3,4,5,6,7,8,9,0};
    func(x);
}

and this is how you'd do it for multiple arrays

#include<iostream>

template <typename T, int s1, int s2>
void func(T (&a) [s1], T (&b) [s2], int c)
{
   std::cout<<"a=";
   for (int i = 0; i < s1; ++i) { std::cout<< a[i]; a[i]=56; }
   std::cout<<"\nb=";
   for (int i = 0; i < s2; ++i) { std::cout<< b[i]; }
   std::cout<<"\nc="<<c<<"\n";
}

int main()
{
   int x[10] = {1,2,3,4,5,6,7,8,9,0};
   int y[5] = {5,4,3,2,1};
   func(x,y,6);
   std::cout<<"\n\n";
   for (int i = 0; i < 10; ++i) { std::cout<< x[i]; }
}


All the best!

No comments: