简体   繁体   中英

basic function printing 0's rather than specified numbers C

I have this basic code that is meant to ask the user how many integers to input, get the user to input specified numbers for each integer and then reprint the integers the user typed in, except instead of printing the integers it just prints 0's

int getInts(int * integersArray, int numInput);

int main() {
    int * integersArray;
    int numInput;
    int i;

    numInput = getInts(integersArray, numInput);

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

    return 0;
}


int getInts(int * integersArray, int numInput) {
    int i;

    printf("Please enter the number of integers you want to input\n");
    scanf("%d", &numInput);

    integersArray = (int *) malloc(sizeof(int) * numInput);

    for (i = 0; i < numInput; i++) {
        printf("please enter integer %d: ", i+1);
        scanf("%d", &(integersArray[i]));
    }

    return numInput;
}

Move these lines:

printf("Please enter the number of integers you want to input\n");
scanf("%d", &numInput);
integersArray = (int *) malloc(sizeof(int) * numInput);

to main , before you call getInts .

The reason why you need this is that getInts receives a copy of integersArray (ie a copy of the pointer), and an assignment within getInts modifies only the copy, and the integersArray in main remains intact.

First you need to understand what passing by value and what passing by reference is.

Observe in the example I have here , how the arguments are passed in the function. The first one is passed by value and the second by reference.

The function holds its own variables, since it has an internal world, that all of its variables live inside. Once the function is terminated, so does its world.

The first argument is copied to the first argument and when the function terminates, the changes made inside the function are forgotten.

However, the second one is passed by reference. As a result the variable inside the function 'points' to the variable that lives in main. So, when the function terminates, all the changes will be remembered in the world of main too.

Now, in your case, you want to pass an array, to dynamically allocate it and fill it. You need to pass the array by reference, so that the changes shall be remembered when the function terminates.

Here is how one could do it:

#include <stdlib.h>
#include <stdio.h>

int getInts(int** integersArray, int numInput);

int main() {
    int * integersArray;
    int numInput;
    int i;

    numInput = getInts(&integersArray, numInput);

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

    return 0;
}

// do I really need to pass numInput, since I return it? No.
int getInts(int** integersArray, int numInput) {
    int i;

    printf("Please enter the number of integers you want to input\n");
    scanf("%d", &numInput);

    *integersArray = malloc(sizeof(int) * numInput);

    for (i = 0; i < numInput; i++) {
        printf("please enter integer %d: ", i+1);
        scanf("%d", &((*integersArray)[i]));
    }

    return numInput;
}

Here, when we malloc something, this means that the memory allocated will not be de-allocated when the function terminates. It will live forever and we ought to de-allocate when we no longer need it, eg at the end of main. If we do not do so, this will produce a memory leak , which is a common logical error.

So, the main should be modified in order to use free() .

int main() {
    int * integersArray;
    int numInput;
    int i;

    numInput = getInts(&integersArray, numInput);

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

    free(integersArray);   // FREE
    return 0;
}

Below is a version, which doesn't return the numInput , but modifies a bit the second argument you have in getInts() .

// changed the prototype
void getInts(int** integersArray, int* numInput);

int main() {
    int * integersArray;
    int numInput;
    int i;

    getInts(&integersArray, &numInput); // pass the numInput by reference!!

    for (i = 0; i < numInput; i++) {
        printf("%d ",integersArray[i]);
    }
    free(integersArray);
    return 0;
}


void getInts(int** integersArray, int* numInput) {
    int i;

    printf("Please enter the number of integers you want to input\n");
    scanf("%d", numInput);

    *integersArray = malloc(sizeof(int) * (*numInput));

    for (i = 0; i < *numInput; i++) {
        printf("please enter integer %d: ", i+1);
        scanf("%d", &((*integersArray)[i]));
    }
}

Notice how numInput is treated inside the body of your function. Also note that I wrote scanf as this

scanf("%d", numInput);

but what really happens is this:

scanf("%d", &(*numInput));

However, operators & and * cancel its other out, as you might already know.

[EDIT]

As alk stated, this provides an excellent chance to learn to use a debugger . There is plenty of info and good tutorials about that in the internet.

Another debugging technique would be using printing messages in the code and see where things don't go as you think they are (remember the good thing with the computers is that they do exactly what we tell them and the bad thing with the computers is that they do exactly what we tell them).

Here is an example of modifying your function for that purpose:

int getInts(int * integersArray, int numInput) {
    int i;

    printf("Please enter the number of integers you want to input\n");
    scanf("%d", &numInput);

    // first step would be to check that you get the numInput right
    printf("numInput is %d\n", numInput);


    integersArray = malloc(sizeof(int) * numInput);

    for (i = 0; i < numInput; i++) {
        printf("please enter integer %d: ", i+1);
        scanf("%d", &(integersArray[i]));
    }

    // check if you read the numbers correctly
    for (i = 0; i < numInput; i++) {
         printf("%d ",integersArray[i]);
    }
    printf("\ngetInts() terminating...\n");

    return numInput;
}

and a possible output would be:

Please enter the number of integers you want to input
1
numInput is 1
please enter integer 1: 2
2 
getInts() terminating...
441172865 

From the output we can see that input value was correctly received by our array, because we print the array inside the function.

However in the main, the array contains garbage..Hmm, what can be wrong? Well you already know from what I wrote before. Your mind should think, the function does it's job good inside her body, but the 'communication' with main has some problem. The problem was that the array wasn't passed by reference.

Also notice, that you should not cast what malloc returns. Google for more (one result of googling is here ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM