You set your pointer to the address of an array that is in the stack frame of getVar
.
When that function returns, the stack frame is popped and those values go out of scope. (i.e. they can/should no longer be accessed).
When you call printf
from main
, the call will reuse that stack memory space previously used by getVar
. Likewise, for printFunc
.
So, whatever they use it for, it overwrites/corrupts the values that where created by getVar
There are two ways to remedy this:
- Have
getVar
do a malloc
- Have
main
pass the address of an array [in main
's stack frame] to getVar
For a more elaborate explanation of pointers and arrays, see my answer here: Issue implementing dynamic array of structures
Here is the version with malloc
:
#include <stdio.h>
#include <stdlib.h>
int *
getVar()
{
int *values = malloc(sizeof(int) * 3);
printf("Enter 3 values:\n");
scanf("%d", &values[0]);
scanf("%d", &values[1]);
scanf("%d", &values[2]);
return values;
}
void
printFunc(int *arrPointer)
{
int i;
for (i = 0; i < 3; i++) {
printf("%d", *arrPointer);
arrPointer++;
}
printf("\n");
}
int
main()
{
int *arrPointer;
arrPointer = getVar();
printf("The numbers entered in order are: ");
printFunc(arrPointer);
free(arrPointer);
return 0;
}
Here is the version that uses's a stack variable from main
:
#include <stdio.h>
void
getVar(int *values)
{
printf("Enter 3 values:\n");
scanf("%d", &values[0]);
scanf("%d", &values[1]);
scanf("%d", &values[2]);
}
void
printFunc(int *arrPointer)
{
int i;
for (i = 0; i < 3; i++) {
printf("%d", *arrPointer);
arrPointer++;
}
printf("\n");
}
int
main()
{
int arr[3];
getVar(arr);
printf("The numbers entered in order are: ");
printFunc(arr);
}
UPDATE:
is it possible to return an array or more than 1 variable from a function?
Yes, in a way, but the caller must pass down a place for the extra values.
In the second example above, another way to look at it is that the caller (i.e. main
) is requesting three values from getVar
and provides space for these values in the array.
Another way is for the caller to pass down multiple pointer values that show where to return the values:
#include <stdio.h>
void
getVar(int *val,float *fval)
{
printf("Enter 2 values:\n");
scanf("%d", val);
scanf("%f", fval);
}
int
main()
{
int val;
float fval;
getVar(&val,&fval);
}
But, passing a pointer argument can get tedious if more than two values are desired.
So, in that case, we can pass down the address of a struct
that can have as many return values as we wish:
#include <stdio.h>
struct values {
int val;
float fval;
int count;
int rval;
};
void
getVar(struct values *ret)
{
printf("Enter 3 values:\n");
scanf("%d", &ret->val);
scanf("%f", &ret->fval);
scanf("%d", &ret->count);
ret->rval = rand() % ret->count;
}
int
main()
{
struct values val;
getVar(&val);
}
Note that we could also use the malloc
method combined with the struct
. That is, getVar
does a struct values *ret = malloc(sizeof(struct values));
and then returns this pointer (after filling in the struct).