How to return an array from a function with pointers

11,694

Solution 1

If you don't want to get in trouble learning malloc and dynamic memory allocation you can try this

#include <stdio.h>

void initArray(int n, int array[n]) {
    int i;

    for (i = 0 ; i < n ; i++) {
        array[i] = i * 2; 
    }
}

int main() { /* main should return int */
    int i, n = 5;
    int array[n];

    initArray(n, array);

    printf("Here is the array: ");
    for(i = 0 ; i < n ; i++) { 
        printf("%d ", array[i]); 
    }
    printf("\n\n");
    return 0;
}

as you see, you don't need to return the array, if you declare it in main(), and pass it to the function you can just modify the values directly in the function.

If you want to use pointers, then

#include <stdio.h>

int *initArray(int n) {
    int i;
    int *array;

    array = malloc(n * sizeof(*array));
    if (array == NULL) /* you should always check malloc success */
        return NULL;

    for (i = 0 ; i < n ; i++) {
        array[i] = i * 2; 
    }

    return array;
}

int main() { /* main should return int */
    int i, n = 5;
    int *array;

    array = initArray(n);
    if (array == NULL) /* if null is returned, you can't dereference the pointer */
        return -1;

    printf("Here is the array: ");
    for(i = 0 ; i < n ; i++) { 
        printf("%d ", array[i]); 
    }
    free(array); /* you sould free the malloced pointer or you will have a memory leak */
    printf("\n\n");

    return 0;
}

Solution 2

Edit: iharob's answer is better than mine. Check his answer first.

Edit #2: I'm going to try to explain why your code is wrong

Consider the 2nd line of main() in your question:

int *array[n];

Let's try to read it backwards.

[n]

says we have an array that contains n elements. We don't know what type those elements are and what the name of the array is, but we know we have an array of size n.

array[n] 

says your array is called array.

* array[n]

says you have a pointer to an array. The array that is being pointed to is called 'array' and has a size of n.

int * array[n];

says you have a pointer to an integer array called 'array' of size n.

At this point, you're 3/4 way to making a 2d array, since 2d arrays consist of a list of pointers to arrays. You don't want that.

Instead, what you need is:

int * array;

At this point, we need to examine your function, initArray:

int *initArray(int n){
    int i;
    int *array[n];

    for(i = 0; i < n; i++){
        array[i] = i*2; 
    }

    return array;
}

The second line of initArray has the same mistake as the second line of main. Make it

int * array;

Now, here comes the part that's harder to explain.

int * array;

doesn't allocate space for an array. At this point, it's a humble pointer. So, how do we allocate space for an array? We use malloc()

int * array = malloc(sizeof(int));

allocates space for only one integer value. At this point, it's more a variable than an array:

[0]

int * array  = malloc(sizeof(int) * n);

allocates space for n integer variables, making it an array:

e.g. n = 5:

[0][0][0][0][0]

Note:The values in the real array are probably garbage values, because malloc doesn't zero out the memory, unlike calloc. The 0s are there for simplicity.

However, malloc doesnt always work, which is why you need to check it's return value: (malloc will make array = NULL if it isn't successful)

if (array == NULL)
    return NULL;

You then need to check the value of initArray.

#include <stdio.h>
#include <stdlib.h>
int *initArray(int n){
    int i;
    int *array = malloc(sizeof(int) * n);
    if (array == NULL)
        return NULL;

    for(i = 0; i < n; i++){

        array[i] = i*2; 
    }

    return array;
}

int main(){
    int i, n = 5;
    int *array = initArray(n);
    if (array == NULL)
        return 1;

    printf("Here is the array: ");

    for(i = 0; i < n; i++){ 
        printf("%d ", array[i]); 
    }
    free(array);

    printf("\n\n");
    return 0;
}

You can't just return an array like that. You need to make a dynamically allocated array in order to do that. Also, why did you use a 2d array anyway?

int array[5];

is basically (not completely) the same as:

int * array = malloc(sizeof(int) * 5);

The latter is a bit more flexible in that you can resize the memory that was allocated with malloc and you can return pointers from functions, like what the code I posted does. Beware, though, because dynamic memory allocation is something you don't wanna get into if you're not ready for tons of pain and debugging :)

Also, free() anything that has been malloc'd after you're done using it and you should always check the return value for malloc() before using a pointer that has been allocated with it.

Thanks to iharob for reminding me to include this in the answer

Solution 3

Do you want to initialize the array? You can try it like this.

#include <stdio.h>
void initArray(int *p,int n)
{
    int i;
    for(i = 0; i < n; i++)
    {
        *(p+i) = i*2; 
    }

}

void main(void)
{
    int i, n = 5;
    int array[n];

    initArray(array,n);

    printf("Here is the array: ");

    for(i = 0; i < n; i++)
    { 
        printf("%d ", array[i]); 
    }

    printf("\n\n");
}
Share:
11,694
Dren Skywalker
Author by

Dren Skywalker

Student of Computer Science at the University.

Updated on June 04, 2022

Comments

  • Dren Skywalker
    Dren Skywalker almost 2 years

    i'm trying to figure out how to return an array from a function in the main().

    I'm using C language.

    Here is my code.

    #include <stdio.h>
    
    int *initArray(int n){
        int i;
        int *array[n];
    
        for(i = 0; i < n; i++){
            array[i] = i*2; 
        }
    
        return array;
    }
    
    main(){
        int i, n = 5;
        int *array[n];
    
        array[n] = initArray(n);
    
        printf("Here is the array: ");
    
        for(i = 0; i < n; i++){ 
            printf("%d ", array[i]); 
        }
    
        printf("\n\n");
    }
    

    And this is the errors the console gives me:

    2.c: In function ‘initArray’:
    2.c:8:13: warning: assignment makes pointer from integer without a cast [enabled by default]
        array[i] = i*2; 
                ^
    2.c:11:3: warning: return from incompatible pointer type [enabled by default]
        return array;
        ^
    2.c:11:3: warning: function returns address of local variable [-Wreturn-local-addr]
    2.c: In function ‘main’:
    2.c:23:4: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
        printf("%d ", array[i]); 
        ^
    

    It's impossible! I hate being a noob :(

    If you could help, with explanations, I would appreciate! :D