Search code examples
arrayscdynamic-memory-allocation

Why the memory is not allocated to the array?


I was required at college to build a function in C that reads a number of values from a file and then dynamically allocates memory to an array passed by reference using pointers (it must use pointers) and after that we were required to display the values read using another function.
I tried 2 aproaches that I've displayed here:

    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    
    ///Read an 1d array from the file stuff.txt inside of a function
    /// and dinamically allocate memory
    /// after that display on the screen the values readed from file
    
    void getDataFirstFunction(int **a, int *n)
    {
        FILE *f;
        f = fopen("stuff.txt" ,"r");
        if(!f)
        {
            printf("ERROR WHILE OPENING THE FILE!!");
            exit(0);
        } else
        {
           int d;
           fscanf(f,"%d",&(*n));
           ///we dinamically alocate memory
           a = calloc((*n),sizeof(int));
           int i=0;
    
           while(!feof(f))
           {
              fscanf(f,"%d",&a[i++]);
           }
        }
    
        ///if I try to display the values here it works
        ///but when I try to read display them in the display
        ///function it is not going to work anymore
        fclose(f);
    }
    
    int * getData(int **a,int *n)
    {
        FILE *f;
        f = fopen("stuff.txt" ,"r");
        if(!f)
        {
            printf("ERROR WHILE OPENING THE FILE!!");
            exit(0);
        } else
        {
           int d;
           fscanf(f,"%d",&(*n));
           ///we dinamically alocate memory
           a = calloc((*n),sizeof(int));
           int i=0;
    
           while(!feof(f))
           {
              fscanf(f,"%d",&a[i++]);
           }
        }
    
        ///if I try to display the values here it works
    
        fclose(f);
        return a;
    }
    
    void displayValues(int *a,int n)
    {
        for(int i=0;i<n;i++)
        {
            printf("%d\n",a[i]);
        }
    }
    
    int main()
    {
        int *a,*b,n,m;
        getData(a,&n);
        getDataFirstFunction(b,&m);
        displayValues(a,n);
        displayValues(b,m);
        return 0;
    }

However the first function declared with void doesen't work and I can't understand why, because I've intentionally wrote a parameter that is a double pointer so when I allocate memory that memory it is not lost when the variables on the stack are dealocated by the compiler after the function finish it's execution.
The second function named getData does make sense and it works but I don't know if I can make the first function with void to work because it seems like the memory is allocated only to the variable on the stack and then when it finish the execution the reference to the memory location dissapears without having memory allocated to the pointer in main so when I do try to display values on screen the program freezes and then I get nothing.
Thanks in advance.


Solution

  • Inside your functions, a is a copy of a pointer to pointer.
    Here you assigned something else to that copy:

    a = calloc((*n),sizeof(int));
    

    That does not have any effect outside of the function.

    Outside of your functions, a is a pointer to int, it would make sense to write a pointer to int there.
    You could do that (via the copy used within your functions) for example like

    *a = calloc((*n),sizeof(int));
    

    For that effect outside of your functions you should call with the address of the pointer to int

    getData(&a,&n); 
    

    With this int * getData(int **a,int *n) you could assign the returned pointer to int to a outside of your function. But don't here getData(a,&n);. And for returning a pointer to int, this line is not appropriate return a; because it returns a pointer to pointer to int. Which does happen to contain the right value (freshly allocated pointer to int), but that is still incorrect by type. ...

    Note:
    You are relying very much on your fscanf()s working, so the n you are using for size might be uninitialised...
    And you should not use while(!feof(f)),
    Why is “while ( !feof (file) )” always wrong?
    And d seems unused inside of your functions...
    So please heed the recommendation in the comment by M.M. about reading compiler warnings.