Question

Here is a function(returnArr) to read 10 integers and store them in an array. increment each by 2, and return the array base address. Using the base address, the array elements are printed (in three()).

#include<stdio.h>
#include<stdlib.h>
int* returnArr()
{
    int arr[10];
    size_t iter = 0;
    while( iter < 10 )
    {
        scanf("%i",arr+iter);
        arr[iter]+=2;
        printf("%i ",arr[iter]);
        iter+=1;
    }
    return arr;
}

void three()
{
    size_t iter = 0;
    int* arr = returnArr();
    //putchar('\n');
    while( iter < 10 )
    {
        printf("%i ",arr[iter]);
        iter+=1;
    }
    return;
}

int main()
{
    //one();
    //two();
    three();
    return 0;
}

Ideally the program should print garbage values since the address points to the location of a local variable in another function which was called before the array traversal.

But it is actually printing the array elements when the putchar function call is commented, garbage values when the getchar function call is included in the program code.

Using gcc 4.7.2 on Debian.

Can anyone explain this ?

-Newbie

Was it helpful?

Solution

Your program has undefined behavior: you cannot return an array that has been allocated locally:

int* returnArr()
{
    int arr[10];
    ...
    return arr; // <<== This is undefined behavior
}

The results that you see after the call of returnArr are, well, undefined: the memory returned from the function is up for grabs, so it gets altered by arbitrary events, such as making an addition function call.

But it is actually printing the array elements when the putchar function call is commented, garbage values when the getchar function call is included in the program code.

Without the call of putchar the memory of arr stays undisturbed, so you get old values. When you call putchar, its return address is placed on the stack, right at the spot where arr is stored. This is a general problem with undefined behavior - you do not get a "fail fast" behavior, or even a guaranteed failure with it. This answer provides a very nice analogy to what's happening when you return a pointer to local from a function.

To fix this problem, allocate the array dynamically, and free it in the caller, like this:

int *arr = malloc(10*sizeof(int)); // Instead of int arr[10];
...
int* arr = returnArr(); // Call the function
...                     // Use arr here, then...
free(arr);              // free it when you are done.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top