Search code examples
cpointersdynamicmallocprocedure

How can I create a dynamic array in a procedure in C?


I'm new to this fantastic site and I found it very useful in many occasions, but now I'm dealing with a problem which I can't seem to solve. I'm a beginner C student and I'm studying dynamic memory allocation. I want to create a dynamic array of, let's say, integers, allocating memory for it inside a procedure, not in the main function.

This works:

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

int main()
{
        int *numbers; // pointer to create a dynamic array
        int *test; // pointer to test realloc function
        int c;
        size_t i = 0;
        unsigned int dim; // array's length

        // allocate memory for the 1st number 
        numbers = malloc(sizeof(*numbers));
        if (numbers == NULL) {
                fputs("Error while allocating memory!\n", stderr);
        } else {
                printf("Insert the 1 number: ");
                scanf("%d", &numbers[0]);
                ++i;

                /* allocate memory for the other numbers,
                 * until the user inputs EOF
                 */
                while (!feof(stdin)) {
                        test = realloc(numbers, (sizeof(*numbers) * (i + 1)));
                        if (test == NULL) {
                                fputs("Error while allocating memory!\n", stderr);
                        } else {
                                numbers = test;
                                printf("Insert the %u number: ", i + 1);
                                scanf("%d", &numbers[i]);
                                ++i;
                        }
                }
                dim = --i;

                // print the array, 5 numbers per line
                 for (i = 0; i < dim; ++i) {
                        if (i % 5 == 0) {
                                puts("");
                        }
                        printf("%d ", numbers[i]);
                }
                puts("");
        }

        getchar();
        return 0;
}

But I want to do this (which doesn't work):

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

void get_numbers(int **numbers, unsigned int *dim);

int main()
{
        int *numbers; // pointer to create a dynamic array
        size_t i = 0;
        unsigned int dim; // array's length

        get_numbers(&numbers, &dim);

        // print the array, 5 numbers per line
         for (i = 0; i < dim; ++i) {
                if (i % 5 == 0) {
                        puts("");
                }
                printf("%d ", numbers[i]);
        }
        puts("");

        getchar();
        return 0;
}

void get_numbers(int **numbers, unsigned int *dim)
{
        int *test; // pointer to test realloc function
        int c;
        size_t i = 0;

        // allocate memory for the 1st number 
        *numbers = malloc(sizeof(*numbers));
        if (*numbers == NULL) {
                fputs("Error while allocating memory!\n", stderr);
        } else {
                printf("Insert the 1 number: ");
                scanf("%d", &numbers[0]); // Maybe the error is here
                ++i;

                /* allocate memory for the other numbers,
                 * until the user inputs EOF
                 */
                while (!feof(stdin)) {
                        test = realloc(*numbers, (sizeof(*numbers) * (i + 1)));
                        if (test == NULL) {
                                fputs("Error while allocating memory!\n", stderr);
                        } else {
                                *numbers = test;
                                printf("Insert the %u number: ", i + 1);
                                scanf("%d", &numbers[i]);
                                ++i;
                        }
                }
                *dim = --i;
        }
}       

Do I need to use a pointer to a pointer to int, right? I know I made some mistakes but I can't figure out how to fix them. Thanks in advance for your replies! Bye, Fabio Nardelli


Solution

  • In the first block of code, numbers is of type int*.
    In the second block of code, numbers is of type int**.

    You have not fixed all the places that need to be fixed because of that change.

    My suggestion:

    1. Change the input argument to numbersPtr.
    2. Create a local variable int* numbers.
    3. Before you return from the function, set *numbersPtr to number.

    void get_numbers(int **numbersPtr, unsigned int *dim)
    {
       int* numbers;
    
       ...
    
       *numbersPtr = numbers;
    }
    

    It will be better to change get_numbers to return numbers.

    int* get_numbers(unsigned int *dim)
    {
       int* numbers;
    
       ...
    
       return numbers;
    }
    

    and change its usage as:

    numbers = get_numbers(&dim);