0

I have defined a function to read an array of integers and return it as a pointer.

#include "stdafx.h"
#include <stdio.h>

const int size = 5;

int* getInput();
int main(int argc, _TCHAR* argv[])
{
    int* a = getInput();
    for(int i = 0; i < size; i++){
        printf("%d \n", a[i]);
    }
    return 0;
}

int* getInput(){
    int input[size];
    for(int i = 0; i < size; i++){
        scanf("%d", &input[i]);
    }
    return input;
}

The problem is that with the input of:

1
2
3
4
5

This program prints something like this:

1
5242692
1474139472
872394811
-2

I can't understand why this happens. Can anyone help me with this problem?

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • the array in GetInput is stack allocated, you cannot return a pointer to it. You need to use malloc. – perreal Nov 19 '17 at 13:42

2 Answers2

3

getInput() returns the address of a local array with automatic storage: accessing this object after the function returns has undefined behavior. What you observe is the contents of the array being overwritten by printf as it uses the same space for its own local variables. The behavior is undefined, which means anything can happen, including a program failure.

Also avoid defining global variables, especially with a simple name such as size.

You should pass the destination array and its number of elements:

#include <stdio.h>

int getInput(int *dest, int size);

int main(int argc, char *argv[]) {
    const int size = 5;
    int input[size];

    int n = getInput(input, size);
    for (int i = 0; i < n; i++) {
        printf("%d\n", a[i]);
    }
    return 0;
}

int getInput(int *dest, int size) {
    int i;
    for (i = 0; i < size; i++) {
        if (scanf("%d", &input[i]) != 1)
            break;
    }
    /* return the number of integers successfully read from stdin */
    return i;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
1

The array in the function - it's lifetime ends when the function ends. To do what you expect to do you need to allocate memory and return it. because it's lifetime will be till the program ends or you free it.

You might want to do:

int *input = malloc(sizeof *input *size);
if( input == NULL)
{
   // error
}

..
return input;

In your case you are invoking undefined behavior by accessing variables that is out of scope.

int* getInput(){
    int *input = malloc(sizeof *input *size);
    if( input == NULL)
    {
       fprintf(stderr,"%s","Error in allocation");
       exit(1);
    }
    for(size_t i = 0; i < size; i++){
        scanf("%d", &input[i]);
    }
    return input;
}

The allocated memory that you get using malloc should be freed to avoid memory leak. You can do it when you are done working with it.

In main() you just need to free the memory.

int main(int argc, _TCHAR* argv[]){
    ...
    ...
    free(a);
}

Here instead of using a constant variable size you can pass it to the function and allocate different amount of memory and get input from user accordingly. For large value of size you can pass the value of size to the function.

It's good to check the return value of scanf(). So the call to it should be

if( scanf("%d",&input[i])== 1)
  // ok

You can check a detail discussion here.

user2736738
  • 30,591
  • 5
  • 42
  • 56