简体   繁体   中英

How to properly allocate memory for an array pointer passed as an argument in C

I am mixed up on my pointers and references. I want to create a pointer in a main function and set it to null. I would like to pass that pointer to another function that creates an array on the heap, fills it, and returns the size of the created array.

I tried to find another article about this topic but failed to find one that allocated memory from within the function. The example code below illustrates the concept but I am not writing a program to accomplish any specific task.

int fillarray(/* pointer to an array */){

    // malloc the array to size n
    // fill array with n elements

return n;
}

int main(){

    int* array = NULL;
    int size = fillarray(/* pass the pointer by reference */);

    for(int i = 0; i < size; i++) printf("%d\n", array[i]);

    free(array);

return 0;
}

UPDATE:

Thank you all for your comments. I learned a ton about pointers working through this problem. The code below accomplishes what I need it to. Thank you @Lundin. Your answer led me to the actual solution. Thank you @ssd as well. Your visual helped me gain some intuition on what I was looking at in the code.

int fillarray(int** array){

    *array = (int*)malloc(2 * sizeof(int));
    (*array)[0] = 0;
    (*array)[1] = 1;

return 2;
}

int main(){

    int* array = NULL;
    int size = fillarray(&array);
    for(int i = 0; i < size; i++) printf("%d\t", array[i]);

return 0;
}

Strictly speaking there are no "references" in C, everything is passed by value. Although the term "pass by reference" is language agnostic and really just means pass an address to the data. (C++ has a language concept called references, but it's really just glorified read-only pointers.)

So to achieve what you want, you have to pass the address of the pointer itself. That way, the function can access the pointer and set it to point at a new address. Thus declare the function as int fillarray (int**) call the function as fillarray(&array) . The result of malloc needs to be assigned to where the pointer-to-pointer points at - it points at the address of the original pointer declared variable in main().

As for allocating a variable size, you will have to add an additional plain integer parameter to the function for that.

I do agree & consent Lundin's answer but to be more conceptual, I'll add the drawing below, for I had the same pain in the past understanding pointers.

  • The first integer pointer below ( int *a ) is at memory address 4c4b40 and its value is set to zero (which means this pointer a is set to null ).

  • The second integer pointer ( int *b ) is at memory address 4c4b48 and its value is set to 4c4b58 (which means, this pointer points to memory address 4c4b58 with a length of integer). If that address corresponds to variable int x = 16 (hexadecimal 10 is equal to 16), then dereferencing pointer b will give you an integer value of 16 ( *b = 16 because x = 16 ).

  • The third memory is another character string pointer, which points to a memory address somewhere down below.

Returning to the answer:

If you are to change the address of the first pointer ( a ) in order to point to the variable x , then the function you're calling needs to receive the address of the pointer (not the pointer, itself); ie &a instead of a , which corresponds to 4c4b40 . The function called will receive the address 4c4b40 as a memory address and change its value from 000000 to 4c4b58 . The function decoration, of course, will contain an int ** ; for, if an integer pointer is an int * , a pointer to a pointer will be an int ** .

在此处输入图片说明

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