# Thread: How do I return a reference to an array from a function

1. ## How do I return a reference to an array from a function

Hey guys!

First post here. Trying to figure out how to return a reference to an array from a function. Here is a snippet of code I am working with:

Code:
```int (*getArray()){int arr= {2, 4, 6, 8, 10};return &arr; }
int main( int argc, char* argv[] ) {int (*arr)= getArray();//Iterate over arrayfor( int i= 1; i<= 5; i++ ) printf("%d\n", arr[i]);    return 0; }```
This is the output (newlines omitted)

Code:
`20 40 60 80 100`

So my questions are:

1. Where are these zeros coming from? How can I change the code
to lose them?
2. The compiler warns me that I'm returning an address to the array,
am I to manually relinquish the memory of the array? Is this a
closure?
3. Is this a good way of going about returning an array from a function?
What are some alternative methods?
4. How do I make my code pretty/more legible for future posts? 2. 1. Where are these zeros coming from? How can I change the code to lose them?

It's a coincidence that the values look like your values times 10. If you change your 5 values to anything else, you will still get the same output. The output is actually the total size of the array (20 bytes) times 1, 2, 3, 4 and 5. Indexing off of the array pointer like arr[i] (with indices 1 to 5) causes that. Instead you need to use it like (*arr)[i] (and the indices should be 0 to 4). But there are more problems than just that.

2. The compiler warns me that I'm returning an address to the array, am I to manually relinquish the memory of the array? Is this a closure?

No, it is not a closure. Do you not know what local variables are? You can't return the address of a (non-static) local variable from a function since they are stored on the stack and aren't reliably accessible after the function returns since the stack space will be reused.

3. Is this a good way of going about returning an array from a function? What are some alternative methods?

The closest thing to your code that works is to declare the array as static so it's not stored on the stack and remains accessible after the function returns.
Code:
```#include <stdio.h>

int (*getArray()) {
static int arr = {2, 5, 6, 8, 10};
return &arr;
}

int main() {
int (*arr)= getArray();
for (int i = 0; i < 5; i++)  // indices are 0 to 4
printf("%d ", (*arr)[i]); // must access it like this
putchar('\n');
return 0;
}```
But that's overkill since almost the same thing can be achieved more simply like this:
Code:
```#include <stdio.h>

int *getArray() {
static int arr = {2, 4, 6, 8, 10};
return arr;
}

int main() {
int *arr = getArray();
for (int i = 0; i < 5; i++)
printf("%d ", arr[i]);
putchar('\n');
return 0;
}```
However, that's not how it would usually be done. There are two usual ways to return an array:

1. Dynamically allocate the array and return that.
Code:
```#include <stdio.h>
#include <stdlib.h>

int *getArray(int size) {
int *a = malloc(size * sizeof *a);
for (int i = 0; i < size; i++)
a[i] = i * 2;
return a;
}

void printArray(const int *a, int size) {
for (int i = 0; i < size; i++)
printf("%d ", a[i]);
putchar('\n');
}

int main() {
int *a = getArray(10);
printArray(a, 10);
free(a);  // remember to free the memory
return 0;
}```
b. Declare the array in the caller and pass it in.
This is often the best way.
Code:
```#include <stdio.h>
#include <stdlib.h>

void fillArray(int *a, int size) {
for (int i = 0; i < size; i++)
a[i] = i * 2;
}

void printArray(const int *a, int size) {
for (int i = 0; i < size; i++)
printf("%d ", a[i]);
putchar('\n');
}

int main() {
int a;
fillArray(a, 10);
printArray(a, 10);
return 0;
}``` 3. I didn't explain exactly why your original code prints 20, 40, 60, 80, 100.

The first thing to note is that gcc is returning a NULL pointer from your getArray function. Since returning the address of a local variable is undefined behaviour, gcc is allowed to return anything it wants. Returning NULL is most likely to cause a predictable failure and alert the programmer to the problem. If it returned the actual address then the program might seem to work at first but suddenly stop working when you change something that seems unrelated. That bug would be harder to track down.

Array indexing, a[i], is basically just shorthand for *(a + i). a + i is "pointer arithmetic", which adds the size of the object in bytes to the base pointer a, and the * dereferences the resulting pointer. Since NULL is basically 0 and the array is 20 bytes long, you get 0 + i * 20, which gives 0, 20, 40, 60, 80 for i = 0, 1, 2, 3, 4. (You originally used 1 to 5, giving 20 to 100).

So the only thing left to explain is why dereferencing a pointer with the value of 0, 20, 40, etc doesn't cause a segfault. The answer is that it isn't being dereferenced. Whether you print *(arr + i) or (arr + i) (with arr being what you returned from your original function), gcc generates exactly the same assembly code, basically what you would expect with the latter. Presumably this is because the address of an array is the address of its first element, i.e., given int a, a and &a are the same. So the compiler treats &a and *&a essentially the same way. Popular pages Recent additions array, int, pointer;, reference, return
{"ft_lang_label":"__label__en","ft_lang_prob":0.7340316,"math_prob":0.93887675,"size":2684,"snap":"2021-43-2021-49","text_gpt3_token_len":788,"char_repetition_ratio":0.120149255,"word_repetition_ratio":0.17786561,"special_character_ratio":0.3375559,"punctuation_ratio":0.16859505,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.983343,"pos_list":[0,1,2,3,4,5,6,7,8,9,10,11,12],"im_url_duplicate_count":[null,null,null,null,null,null,null,null,null,null,null,null,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2021-12-01T04:14:58Z\",\"WARC-Record-ID\":\"<urn:uuid:f4f3f7c7-fe06-4acf-9074-fa810d7e0885>\",\"Content-Length\":\"55781\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:3ac08ee9-757a-458b-afc9-3e92d6d06d73>\",\"WARC-Concurrent-To\":\"<urn:uuid:0fdb1083-8335-4b9f-aea9-4a84dfb58e6f>\",\"WARC-IP-Address\":\"198.46.93.160\",\"WARC-Target-URI\":\"https://cboard.cprogramming.com/c-programming/176339-how-do-i-return-reference-array-function.html?s=38e8f418b16f205492bcfd561652028a\",\"WARC-Payload-Digest\":\"sha1:EBTZLXI2PDJZJSYZOIK5EUYBSOMICWQ4\",\"WARC-Block-Digest\":\"sha1:XX4THB7HIGSKZC73VPG7BDS3PQUDOI7I\",\"WARC-Identified-Payload-Type\":\"application/xhtml+xml\",\"warc_filename\":\"/cc_download/warc_2021/CC-MAIN-2021-49/CC-MAIN-2021-49_segments_1637964359082.78_warc_CC-MAIN-20211201022332-20211201052332-00346.warc.gz\"}"}