Search code examples
cfunctiondynamic-memory-allocation

Dynamically memory allocation within a function does not work, but no error occured


I want to allocate memory for a array of chars. I wrote a function therefore, which return values tells me, that everything works fine, if I check it. But when i try to write in the array a segmentation error occurs. If i allocate the memory whitout the function (the commented area of the sourcode), everything seems to work fine.

#include <stdio.h>
#include <stdlib.h>
#define ENWIK8 100000000
#define FILEPATH_INPUT "enwik8"
#define FILEPATH_OUTPUT "ergebnis/enwik8"

int array_alloc(char* array, int size);
int array_fill(FILE* file, char* path, char* array);

int main()
{

    FILE* enwik8_file;
    char *text_original;
    array_alloc(text_original, ENWIK8);

//THIS CODE WOULD WORK BUT NOT THE FUNCTION WITH SAME CODE
//   text_original = calloc(ENWIK8,sizeof(char));
//        if(text_original == NULL)
//        {
//            perror("Allocating array not possible!");
//            return -1;
//
//        }

    //Leads to: segmentation fault, if the function is used 
    //instead of the code above
    text_original[1000000] = 'a';
    return 0;
}



int array_alloc(char* array, int size)
{

    array = (char*)calloc(size,sizeof(char));
    if(array == NULL)
    {
        perror("Allocating array not possible!");
        return -1;

    }
    else
    {
        return 0;
    }
}

Solution

  • In array_alloc, you're assigning to a local variable:

    array = (char*)calloc(size,sizeof(char));
    

    Any changes to array are only visible here and not reflected in the calling function. As a result, text_original is still uninitialized after array_alloc returns. You then read and dereference that invalid pointer which invokes undefined behavior, which in this case causes your program to crash.

    You need to change the function to accept a pointer to a pointer and pass the address of text_original from main. So change the function to this:

    int array_alloc(char **array, int size)
    {
        *array = calloc(size, 1);
        if (*array == NULL)
        {
            perror("Allocating array not possible!");
            return -1;   
        }
        return 0;
    }
    

    And call it like this:

    array_alloc(&text_original, ENWIK8);