Yulong Ao
Yulong Ao

Reputation: 1261

How to passing the pointer parameters and return them right?

Here is my code sample:

#include <stdio.h>
#include <stdlib.h>
void foo(int size, int new_size, int * ptr1, double * ptr2) {
    int i;
    new_size = size * 2;
    ptr1 = (int *) calloc(new_size, sizeof(int));
    ptr2 = (double *) calloc(new_size, sizeof(double));

    for (i = 0; i < new_size; i++) {
        ptr1[i] = 1;
        ptr2[i] = 2;
    }
}
int main(){
    int i, size = 4, new_size = 4;
    int *ptr1 = NULL;
    double *ptr2 = NULL;

    foo(size, new_size, ptr1, ptr2);

    for (i = 0; i < new_size; i++) {
        printf("new_size: %d\n", new_size);
        printf("ptr1: %d, ptr2: %f\n", ptr1[i], ptr2[i]);
    }

    free(ptr1);
    free(ptr2);

    return 0;
}

And I have to malloc space and assign data to ptr1 and ptr2 in foo function (because I don't know the new size of them in main functin) and then use them in the main function.
Why the code doesn't work? And How to implement the above process I want?

Upvotes: 0

Views: 49

Answers (2)

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53016

Pass the addresses of the pointers, modify the pointers in the functions and thats all, other that that I have a few observations on your code

  1. Don't cast the return value of malloc(), it's not necessary in c, and it hurts your code readability.

  2. Always check the return value of malloc() and pretty much any function that returns a value, because normally there is a special value indicating failure, and you don't want your program to misbehave under extraordinary conditions.

This is a version of your own code with the main issue addressed and also the observations above.

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

int foo(int size, int new_size, int ** ptr1, double ** ptr2) {
    int        i;
    new_size = size * 2;

    *ptr1 = malloc(new_size * sizeof(int));
    *ptr2 = NULL;
    if (*ptr1 == NULL)
        return 1;

    *ptr2 = malloc(new_size * sizeof(double));
    if (*ptr2 == NULL) {
         free(*ptr1); 
         return 2;
    }

    for (i = 0; i < new_size; i++) {
        (*ptr1)[i] = 1;
        (*ptr2)[i] = 2;
    }

    return 0;
}

int main() {
    int i, size = 4, new_size = 4;
    int    *ptr1 = NULL;
    double *ptr2 = NULL;

    if (foo(size, new_size, &ptr1, &ptr2) != 0)
        return -1;
    for (i = 0; i < new_size; i++) {
        printf("new_size: %d\n", new_size);
        printf("ptr1: %d, ptr2: %f\n", ptr1[i], ptr2[i]);
    }

    free(ptr1);
    free(ptr2);

    return 0;
}

In c you always pass parameters by value, it might be confusing because you are passing a pointer, but a pointer is just another variable which stores a memory address, that address is changing inside the foo() function but it's only being written into the local pointer ptr1.

Passing the address writes the value to the original pointer in main().

Upvotes: 2

Eric Fortin
Eric Fortin

Reputation: 7603

You can pass the address of the pointer to the function like so:

void foo(int size, int new_size, int ** ptr1, double ** ptr2) {
    int i;
    new_size = size * 2;
    *ptr1 = (int *) calloc(new_size, sizeof(int));
    *ptr2 = (double *) calloc(new_size, sizeof(double));

    for (i = 0; i < new_size; i++) {
        (*ptr1)[i] = 1;
        (*ptr2)[i] = 2;
    }
}

and in main

foo(size, new_size, &ptr1, &ptr2);

Your code didn't work because parameter are passed by value. ptr1 and ptr2 while being pointers are still passed by values so any modification to them(compared to modification to what they point to) will not remain after the function.

Upvotes: 3

Related Questions