Home > other >  Memory leak in C and i don't know how to fix it
Memory leak in C and i don't know how to fix it

Time:10-11

This is the leak:

==259134== HEAP SUMMARY:
==259134==     in use at exit: 6 bytes in 1 blocks
==259134==   total heap usage: 3 allocs, 2 frees, 1,036 bytes allocated
==259134== 
==259134== Searching for pointers to 1 not-freed blocks
==259134== Checked 68,872 bytes
==259134== 
==259134== 6 bytes in 1 blocks are definitely lost in loss record 1 of 1
==259134==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==259134==    by 0x109327: ft_strjoin (in /nfs/homes/jotavare/Downloads/a.out)
==259134==    by 0x109474: main (in /nfs/homes/jotavare/Downloads/a.out)
==259134== 
==259134== LEAK SUMMARY:
==259134==    definitely lost: 6 bytes in 1 blocks
==259134==    indirectly lost: 0 bytes in 0 blocks
==259134==      possibly lost: 0 bytes in 0 blocks
==259134==    still reachable: 0 bytes in 0 blocks
==259134==         suppressed: 0 bytes in 0 blocks

This is the code:

#include<stdlib.h>

int ft_strlen(char *str)
{
    int i;

    i = 0;
    while (str[i] != '\0')
        i  ;
    return (i);
}

char    ft_strcat(char *dest, char *src)
{
    int a;
    int b;
    char    *temp;

    a = 0;
    b = 0;
    temp = dest;
    a = ft_strlen(temp);
    while (src[b] != '\0')
    {
        temp[a   b] = src[b];
        b  ;
    }
    temp[a   b] = '\0';
    return (*dest);
}

int strs_length(int size, char **strs, char *sep)
{
    int i;
    int len;

    i = 0;
    len = 0;
    while (i < size)
    {
        len  = ft_strlen(strs[i]);
        i  ;
    }
    len  = ft_strlen(sep) * (size - 1);
    return (len   1);
}

char    *ft_strjoin(int size, char **strs, char *sep)
{
    char    *arr;
    char    *aux;
    int     i;
    int len;
    
    len = strs_length(size, strs, sep);
    i = 0;
    arr =malloc(sizeof(char) * (len));
    arr[0] = 0;
    aux = arr;
    if (size == 0)
    {
        arr[size] = 0;
        return (arr);
    }
    if (!arr)
        return (NULL);
    while (i < size)
    {
        ft_strcat(aux, strs[i]);
        if (i < size - 1)
            ft_strcat(aux, sep);
        i  ;
    }
    aux[ft_strlen(aux)] = '\0';
    return (aux);
}

#include <stdio.h>

int main()
{
    char *text[10];
    text[0] = "1";
    text[1] = "2";
    text[2] = "3";
    text[3] = "4";
    text[4] = "5";
    text[5] = "6";
    text[6] = "7";
    text[7] = "8";
    text[8] = "9";
    text[9] = "10";

    printf("%s\n", ft_strjoin(3, text, " "));
    
    free(ft_strjoin(3, text, " "));
    return(0);
}

This is the exercise:

  • Autorized functions: malloc

  • Write a function that will concatenate the set of pointing strings

  • strs separating them with sep.

  • If size is 0, we need to return a string that we can free().

  • It must be prototyped as follows:

char *ft_strjoin(int size, char **strs, char *sep);

CodePudding user response:

You are making this call:

printf("%s\n", ft_strjoin(3, text, " "));

But you don't capture the return value from ft_strjoin and free it, so that's a memory leak.

CodePudding user response:

Your code does this:

  • Some stuff with the text array
  • Calls ft_strjoin(3, text, " ") and prints the string whose address it returns
  • Calls ft_strjoin(3, text, " ") again and frees the string whose address it returns

The first call to ft_strjoin allocates a string and returns the address of it. The string is never freed. Only the string which is allocated by the second call is freed.

To print and free the string which is allocated by the first call, you would have to store its address in a variable, then print it, using the variable, then free it, using the variable, so that the program only calls ft_strjoin once, and then does both things with the same string which is allocated by that call.

CodePudding user response:

This line

free(ft_strjoin(3, text, " "));

calls ft_strjoin again, which takes some more memory, and frees it afterward. In other words, it has no effect except some wasted CPU cycles. Instead of calling ft_strjoin again, you have to capture the output of the first ft_strjoin (the one in printf), save it in a pointer variable and free it after use.

CodePudding user response:

The code is calling ft_strjoin twice and each call allocates a block of memory, but only one of those allocated blocks is being freed.

The first call to ft_strjoin is from an argument of a printf call here:

    printf("%s\n", ft_strjoin(3, text, " "));

The allocated memory is not freed by printf and no pointer to the allocated memory has been saved elsewhere, so all references to the allocated memory have been lost. This is a memory leak.

The second call to ft_strjoin is from the call to free here:

    free(ft_strjoin(3, text, " "));

The allocated memory from the second call is being freed immediately by the call to free. Nothing useful has been done, but at least it is not a memory leak.


The code should save the result of the first call to ft_strlen so that it can free the memory when it is no longer needed:

    char *joined = ft_strjoin(3, text, " ");
    printf("%s\n", joined);
    free(joined);
  •  Tags:  
  • c
  • Related