0

I'm supposed to recieve and print 3 values but using pointers and functions for each part. arrPointer is the pointer to the array, it goes to the getVar function recieves 3 inputs from the user, puts them in an array and returns the address of the array to main. Then using that address it prints the 3 variables. Or at least it's supposed to. What am I doing wrong?

#include <stdio.h>

int getVar()
{
    int *arrPointer;
    int values[3];

    printf("Enter 3 values:\n");
    scanf("%d", &values[0]);
    scanf("%d", &values[1]);
    scanf("%d", &values[2]);

    arrPointer = values;
    return(arrPointer);
}

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);
}
ythhtrg
  • 11
  • 2
  • Your compiler should have told you that the function `getVar()` is used inconsistently: it is declared to return an `int`, but returns an `int*`. – DYZ Dec 09 '18 at 19:47

3 Answers3

2

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:

  1. Have getVar do a malloc
  2. 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).

Craig Estey
  • 30,627
  • 4
  • 24
  • 48
1

There are two problems:

  1. The values[3] array is declared in the getVar() function. After the function ends, the space that was allocated for int values[3] goes out of scope. The solution of this problem is to allocate memory dinamically: int* values = (int *)malloc(sizeof(int) * 3);
  2. The return type of the function getVar() should be of pointer type. Change int getVar() to int* getVar()
Victor10
  • 96
  • 7
0

to save values to an array you will need to set each position to the array with a variable(int), as you did. But you can't do arrPointer = values. Also you need to pass the pointers to the functions, not to declare them again. Hope this helps and works

 #include <stdio.h>

int getVar(int *values[])
{
    printf("Enter 3 values:\n");
    scanf("%d", &values[0]);
    scanf("%d", &values[1]);
    scanf("%d", &values[2]);

    return values;
}

void printFunc(int *values[])
{
    int i;
    for(i = 0; i<3; i++)
    {
       printf("%d", values[i]);


        }
    printf("\n");
}

int main()
{
    int *arrPointer;
    int *values[3];
    getVar(values);

    printf("The numbers entered in order are: ");
    printFunc(values);
}
T.ChD
  • 41
  • 4