Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to pass a dynamically allocated array to a function that requires an array reference?

A note upfront: I know that it's not a good idea to do what I ask for here. This is just a question arising from morbid language curiosity, not from practical use. The rules that I apply here are completely arbitrary.

Let's say we have a function that is exactly defined as the following. It must not be changed to anything but this, no template or function overloading allowed. The implementation of this function must also not change (and can be treated as unknown). We know however that the parameter is used as an out parameter.

void my_func(int (&arr)[10]);

In a different function we allocate an array dynamically. This allocation must also not change, we are not allowed to allocate on the stack. Also no further allocations are allowed.

int* my_arr = new int[10];

Is it possible to somehow call my_func and pass it my_arr? In other words, is it somehow possible to trick the type system into treating my_arr as an array rather than a pointer?

Naïve castings don't do the trick, all of them lead to compile errors:

my_func((int[10])my_arr);
my_func(static_cast<int[10]>(my_arr));
my_func(reinterpret_cast<int[10]>(my_arr));

Another note: I want to trick the type system. I don't want to copy the data from a stack array etc. Why? Again: Morbid curiosity.

like image 853
Brotcrunsher Avatar asked Mar 18 '21 12:03

Brotcrunsher


2 Answers

You can use reinterpret_cast for this. Using an alias for the array type to make the code easier to read, you would have something like:

void my_func(int (&arr)[10])
{
    for (auto e : arr)
        std::cout << e << " ";
}

int main()
{
    using array_t = int[10];
    int* my_arr = new int[10]{1,2,3,4,5,6,7,8,9,10};
    my_func(reinterpret_cast<array_t&>(*my_arr));
}

And you can see that working at this live example.

like image 156
NathanOliver Avatar answered Oct 26 '22 23:10

NathanOliver


Not that I would recommend doing anything of this sort...

#include <iostream>

void my_func(int (&arr)[10])
{
    std::cout << "Address: " << &arr << std::endl;
    for (int i=0; i<10; ++i)
        std::cout << arr[i] << std::endl;
}

int main()
{
    int *ptr=new int[10];

    for (int i=0; i<10; ++i)
        ptr[i]=i;
    std::cout << "Pointer: " << ptr << std::endl;
    my_func(*( int (*)[10])ptr);
    return 0;
}

Instead of the C-style cast, reinterpret_cast should also work. The trick is to get a pointer to the array, first, then dereference it. Voila, a reference to an array.

like image 27
Sam Varshavchik Avatar answered Oct 26 '22 22:10

Sam Varshavchik