Search code examples
cmemorymallocrealloc

Dynamic memory allocation with char


I'm trying to allocate memory only if i need it for the next while.

char *str = malloc(sizeof(char));
int i = 0;

while(something == true){
    str[i] = fgetc(fp);
    str = realloc(str, strlen(str)+1);
    i++;
}

free(str);

But for some reason the code above give me an "Invalid read of size 1" at strlen().


Solution

  • strlen will not determine the size of the allocated char array even if it contains a null terminated string. See proposed fix although I do not like the code structure overall: You will always end up with an extra allocated character.

    char *str = malloc(sizeof(char));
    int i = 0;
    
    while(something == true){
        str[i] = fgetc(fp);
        str = realloc(str, (i+2)*sizeof(char));
        i++;
    }
    // str[i*sizeof(char)]='\0'; <-- Add this if you want a null terminated string
    
    free(str);
    

    I would propose the following code that would avoid allocating the extra character:

    char *str = NULL;
    int i = 0;
    
    while(something == true){
        str = realloc(str, (i+1)*sizeof(char));
        str[i] = fgetc(fp);
        i++;
    }
    
    free(str);
    

    As per documentation, "In case that ptr is a null pointer, the function behaves like malloc, assigning a new block of size bytes and returning a pointer to its beginning."

    This is in case you are not reading text and not planning to use such functions as strlen, strcat...

    Chunk at a time allocation:

    char *str = malloc(sizeof(char));
    int i = 0;
    const int chunk_size = 100;
    
    while(something == true){
        str[i] = fgetc(fp);
        if (i % chunk_size == 0)
            str = realloc(str, (i+1+chunk_size)*sizeof(char));
        i++;
    }
    // str[i*sizeof(char)]='\0'; <-- Add this if you want a null terminated string
    
    free(str);