user3555081
user3555081

Reputation: 45

C function returning structure data through one of the arguments

I have an issue when using pointer parameters in a function to return values. The function correctly loads all values inside the function, but then somehow fails to pass the pointer value to the variable in the arguments.

In my case, i wrote a function witch returns 1 or 0 depending on whether allocation of memory in question failed or not, and as one of the parameters, takes a pointer to a list that needs to be entered. The structure of the list looks like this:

typedef struct sList {
    int id;
    char first_name[30];
    char last_name[30];
    struct sList *next;
} tList;

The function looks like this:

int readList(tList *start, int n){
    tList *head = NULL;
    tList *tail = NULL;
    int i;
    for (i = 0; i < n; i++){
        tList *tmp = malloc(sizeof(tList));
        if (tmp == NULL) return 0;
        scanf("%d %s %s", &tmp->id, &tmp->first_name, &tmp->last_name);
        tmp->next = NULL;
        if (!head) head = tmp;
        else tail->next = tmp;
        tail = tmp;
    }
    start = head;
    return 1;
}

And the main method:

void main(){    
    tList *start = NULL;
    int n;

    scanf("%d", &n);
    readList(start, n);

    tList *tmp = start;
    while (tmp){
        printf("%d %s %s\n", tmp->id, tmp->first_name, tmp->last_name);
        tmp = tmp->next;
    }
    system("PAUSE");
    return;
}

During debugging, i have concluded that the list head and start inside the function have all the entered values, but as soon as I leave the function and return to the main program the start list goes bananas. So, my question is, am I doing something wrong, because, to my knowledge, this should work in theory. Thanks in advance.

Upvotes: 0

Views: 83

Answers (1)

paxdiablo
paxdiablo

Reputation: 881163

If you want to change a variable from within a function, you need to pass a pointer to it and dereference that pointer within said function. That's how C emulates pass-by-reference.

When that variable is itself a pointer, that means you need to pass a pointer to the pointer, such as with:

int readList(tList **pStart, int n){
    // blah blah blah, setting up head.
    *pStart = head;
    return 1;
}

int main(void){    
    tList *start = NULL;
    int n;

    scanf("%d", &n);
    readList(&start, n);  // Note this, using address-of

    // more blah
    return 0;
}

The text below is an aside to your specific problem but I thought I'd mention it for completeness.

Your main function doesn't conform to the canonical ones allowed by the standard - I've changed it to make that more acceptable but it may not be necessary for your particular implementation, depending on how lax it is. It's still a good idea to follow the standard.

It's also dangerous to assume (in robust code) that scanf() always works. If it returns zero (number of items successfully scanned), n will almost certainly not be what you expect.

You make the same mistake with readList() in that you don't check its return value either. It also has the annoying aspect of causing memory leaks if an allocation fails.

Upvotes: 1

Related Questions