It has been clearly explained how the ownership is transferred. However, I would like to propose a "more traditional" approach. Your code looks very much like something I would happily do in Python - but C is not Python (and Python is not C!), part of learning a new language is learning "how things are done in that language". There is a tendency for programmers that are just learning C to jump at calling malloc here there and everywhere. Try to NOT do that.
Instead of letting the function allocate an array, pass in an array in your calling code, that has space for the things you want to copy. Then return how many lements you actually got, for example something like this:
TYPE new_array[some_size];
int max_size = sizeof(new_array) / sizeof(new_array[0]);
int actual_size;
actual_size = meatSlicer(old_array, new_array, element_start, max_size);
If you want to use malloc to create new_array, then you can of course do so:
TYPE new_array = malloc(some_size * sizeof(TYPE));
int max_size = some_size;
int actual_size;
if (new_array == NULL) panic(); // Do something useful here.
actual_size = meatSlicer(old_array, new_array, element_start, max_size);
...
free(new_array);
I much prefer to use arrays of fixed size, as there is less overhead, and less need to "remember to free later" - the latter is a common problem in code, especially when the code gets a bit more complicated and there are several call levels involved - and if you allocate several items in one function, you need to remember to clean up the first ones if a later allocation fails, for example. Makes life complicated...