1

I want to have a function that reads a file and returns specific lines as a char(string) array of char strings.

I ran Valgrind and it shows that blocks are definitely lost and I don't get why.

if I call the frees directly in the same block as I allocated the memory everything is freed. If I do it outside of the block(in another function) Valgrind shows definitely lost.

Code for which i have lost bytes:

int read_file(char *filename, char * search, char **data)
{
    int counter = 0;
    int size = 1;
    FILE *file;
    file = fopen(filename, "r");
    char c[100];

    while(fgets(c,100, file))
    {
        if(strstr(c,search))
        {
            while(fgets(c, 100, file))
            {
                if(c[0] == '[')
                {
                    break;
                }
                if(c[0] == '\n')
                {
                    continue;
                }
                if(counter+1 > size)
                {
                    data = realloc(data,++size);
                }
                data[counter] = malloc(sizeof(**data)*(strlen(c)+1));
                memcpy(data[counter], c, strlen(c)+1);
                counter++;
            }
        }
    }
    fclose(file);
    return size;
}

void free_pointer(char **data, int size)
{
    for(int i = 0; i < size; ++i)
    {
        free(data[i]);
    }
    free(data);
}

int main()
{
    char **data = malloc(sizeof(*data));
    int x = read_file("test.txt", "omg", data);

//  for(int i = 0; i < x; ++i)
//  {
//      printf("%s", data[i]);
//  }
    free_pointer(data,x);
    return 0;
}

Valgrind shows this:

LEAK SUMMARY:
==17349== definitely lost: 20 bytes in 3 blocks
==17349== indirectly lost: 0 bytes in 0 blocks
==17349== possibly lost: 0 bytes in 0 blocks
==17349== still reachable: 0 bytes in 0 blocks
==17349== suppressed: 0 bytes in 0 blocks

When I add the free line here:


    if(counter+1 > size)
    {
        data = realloc(data,++size);
    }
    data[counter] = malloc(sizeof(**data)*(strlen(c)+1));
    memcpy(data[counter], c, strlen(c)+1);
    //if i add this
    free(data[counter]);
    counter++;

    free(data);
    fclose(file);
    return size;

Valgrind shows this:

HEAP SUMMARY:
==17459== in use at exit: 0 bytes in 0 blocks
==17459== total heap usage: 8 allocs, 8 frees, 4,684 bytes allocated

Update

First error of Valgrind:

Valgrind erros:  
==22271== Invalid read of size 8  
==22271==    at 0x10946C: main (in main)  
==22271==  Address 0x4a34480 is 0 bytes inside a block of size 8 free'd  
==22271==    at 0x4837D7B: realloc (vg_replace_malloc.c:826)  
==22271==    by 0x109299: read_file (in main)  
==22271==    by 0x10944B: main (in main)  
==22271==  Block was alloc'd at  
==22271==    at 0x483577F: malloc (vg_replace_malloc.c:299)  
==22271==    by 0x109426: main (in main) 

Since i changed to the right realloc size i got more errors

==22271== LEAK SUMMARY:
==22271==    definitely lost: 24 bytes in 1 blocks
==22271==    indirectly lost: 17 bytes in 2 blocks
==22271==      possibly lost: 0 bytes in 0 blocks
==22271==    still reachable: 0 bytes in 0 blocks
==22271==         suppressed: 0 bytes in 0 blocks
schauma
  • 23
  • 7
  • 2
    When you re-allocate, `data` changes locally, but the change isn't reflected in the calling function. You'll probably also want to return the count of the strings, not the allocated size. It might be worth ceating a struct that keeps all necessary information of the string array (data, count and size) and work on that. – M Oehm May 09 '19 at 10:14
  • 1
    Read up on `realloc()` and what its arguments are. Your code doesn't give you a bunch of errors in valgrind and/or segfaults? – Shawn May 09 '19 at 10:17
  • okay i fucked up the size to reallocate. So i do (++size)*sizeof(*data)). I still dont get how free works. Yes i get valgrind errors but no segmentation fault – schauma May 09 '19 at 11:34
  • Why are you even using pointer-to-pointer in main() if you just want a one-dimensional array? And as indicated by the duplicate, you don't return the pointer to main() so you get massive leaks. This code seems needlessly complicated overall. – Lundin May 09 '19 at 11:48
  • @Lundin: The data is supposed to be an array of strings of variable length, so `char **` is appropriate. Returning a pointer to malloc'ed memory might not be the best solution if the function should be called repeatedly to fill the array. – M Oehm May 09 '19 at 12:10
  • @MOehm If so, then most of the program is wrong. – Lundin May 09 '19 at 12:31
  • @Lundin Thanks for the duplicate link. I think i now understand the problem. – schauma May 09 '19 at 13:40

0 Answers0