Click here to Skip to main content
15,885,216 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
 How can I solve memory leaks 
in my project. My  code is working but when I check it with -g3 -fsanitize=address flags of makefile its showing  <pre>==7161==ERROR: LeakSanitizer: detected memory leaks
and AddressSanitizer: 140118 byte(s) leaked in 4 allocation(s)

and this is my code for project BSQ -- Find biggest square in a map
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>

typedef struct for_name{
    char* file_name;
    int size_inp;
    int left_a;
    int top_left_b;
    int top_right_c;
    int minim;
    char* content;
} call_name;

typedef struct main_measure{
    int map_size;
    int square_size;
    int index_total;
    char* content_file;
}source_variable;

typedef struct file_hand{
    int fd;
    char* name;
    char* content;
    long int file_size;
}files;

char*  return_size(char* content){
    char* string = (char*)malloc(sizeof(char)* 100);
    int index = 0;
    int inside = 0;
    while(content[index]){
        if(content[index] >= '0' && content[index] <= '9'){
            string[inside++] = content[index];
        }
        index++;
    }
    return string;
}
 

char* take_name(int size, char** array){
    call_name structure;
    structure.size_inp = size;
    structure.file_name = (char*)malloc(sizeof(char)* 18);
    int y = 1;
    if(structure.size_inp > 0)  {
        structure.file_name = array[y];
    }
    return structure.file_name;
}


char* str_make_index(char* file_token, char* name){
    int index = 0;
    files file;
    struct stat st;
    stat(name, &st);
    file.content = (char*)malloc(sizeof(char)*70000);
    for(int inside = 0; inside < st.st_size; inside++){
        if(file_token[inside] == '.' || file_token[inside] == 'o'){
            file.content[index] = file_token[inside];
            index++;
        }
    }
    return file.content;
}

char* take_content(char* name){
    struct stat st;
    files structure;
    structure.content = (char*)malloc(sizeof(char)*70000);
    structure.name = name;
    structure.fd = open(structure.name, O_RDONLY);
    stat(structure.name , &st);
    structure.file_size = st.st_size;
    read(structure.fd, structure.content, structure.file_size);
    close(structure.fd);
    return structure.content;
}

int minem(int a, int b, int c, int index ){
    call_name minimum;
    minimum.left_a = a;
    minimum.size_inp = index;
    minimum.top_left_b = b;
    minimum.top_right_c = c;
    if(index == 0){
        return 0;
    }
    if( minimum.left_a == 0 || minimum.top_left_b == 0 || minimum.top_right_c == 0){
        return 0;
    }
    if( (minimum.left_a<minimum.top_left_b) && (minimum.left_a<minimum.top_right_c)){
        minimum.minim = minimum.left_a;
    }
    else if(minimum.top_left_b<minimum.top_right_c){
        minimum.minim = minimum.top_left_b;
    }
    else{
        minimum.minim = minimum.top_right_c;
    }
    return minimum.minim;
}

void sign_bsq(int size_map, int size_square, int index, char* content){
    call_name matrixm;
    matrixm.content = content;
    int n_ind = index;
    int  tgis_inedes = index;
    for(int y = 0; y  < size_square - 1; y++) {
        index--;
    }
    matrixm.left_a = index;
    int topFind = matrixm.left_a;
    for(int y = 0; y  < size_square - 1; y++){
        n_ind -= size_map;
    } 
    matrixm.top_right_c = n_ind;
    for(int y = 0; y  < size_square - 1; y++) {
        topFind -= size_map;
    }
    matrixm.top_left_b = topFind;
    int looper = 0;
    int  sign_stop = 0;
    int a = matrixm.top_left_b;
    int b =  matrixm.top_right_c;
    while(matrixm.content[looper]){
        if(looper % size_map == 0){ 
            if(looper != 0){
                printf("\n");
            }
        }
        if(!sign_stop){
            if(looper >= a && looper <= b){
                printf("x");
                if(looper == b){
                    a += size_map;
                    b += size_map;
                } 
                if(looper == tgis_inedes){
                    sign_stop = 1;
                } 
            }
            else{
                printf("%c", matrixm.content[looper]);
            }
        }
        else{
            printf("%c", matrixm.content[looper]);
        }
        looper++;
    }
}

void my_bsq(int size, char** array){
    call_name defind;
    if(size != 0) {
        defind.file_name = take_name(size, array);
    }
    char* pro_content;
    pro_content = take_content(defind.file_name);
    defind.size_inp= atoi(return_size(pro_content));
    int total_util = defind.size_inp * defind.size_inp + 1;
    defind.content = str_make_index(pro_content, defind.file_name);
    int square_here;
    int matrix[total_util];
    int index = 0;
    int sq_size_biggest[total_util];
    int  ind_next = 0;
    int mine;
    for(int y = 0; defind.content[y]; y++){
        switch(defind.content[y]){
            case '.' :
                matrix[index] = 1;
            break;

            case 'o':
                matrix[index] = 0;
            break;
        }
        index++;
    }
    int loop = 0;
    while(loop < total_util - 1){
        if(loop < defind.size_inp){
            sq_size_biggest[ind_next] = matrix[loop];
            ind_next++;
        }
        else if(loop % defind.size_inp == 0){
            sq_size_biggest[ind_next] = matrix[loop];
            ind_next++;            
        } 
        else{
            defind.top_right_c = abs(loop - defind.size_inp);
            defind.left_a = abs(loop - 1);
            defind.top_left_b = abs((defind.size_inp + 1) - loop);
            mine = minem(sq_size_biggest[defind.top_left_b], sq_size_biggest[defind.top_right_c], sq_size_biggest[defind.left_a], matrix[loop]);
            if(mine != 0) {
                square_here = mine + 1;
            }
            else{
                square_here = matrix[loop];
            }
            sq_size_biggest[ind_next] = square_here;
            ind_next++;
        }
        loop++;
    }
    int big = 0, indexim ;
    for(int l = 0; l < defind.size_inp; l++){
        for(int y = 0; y < total_util - 1; y++){
        if(sq_size_biggest[y] > 1){
            if(big < sq_size_biggest[y]) {
                    big = sq_size_biggest[y];
                    indexim = y;
                }
            }
        } 
    } 
    sign_bsq(defind.size_inp, big,  indexim, defind.content);
    printf("\n");
}

int main(int size, char** array)
{
    if(size != 0) {
        my_bsq(size, array);
    }
    return 0;
}


What I have tried:

I tried to use free and I assigned NULL value for it but I am confused very much with it and it couldn't work
Posted
Updated 22-Mar-23 7:36am

Basically every object that you create using malloc or calloc needs to be released by calling free on it when you are finished with it - if you don't, you get a memory leak.

These can be difficult to track down, particularly in a large code base, but thankfully yours is pretty small. Start by finding every object you create, and then look for the matching free call. Then start thinking about ways the code might skip that call.

This is a pretty common problem, and there are lots of resources on google that may help: How can I solve memory leaks C - Google Search[^]
 
Share this answer
 
OriginalGriff described the issue. In your code there is nothing that releases the memory that was allocated. You have the function take_content which allocates memory for content so there needs to be a corresponding free_content function that de-allocates or releases that memory by calling free. The function str_make_index also allocates content's memory but the same free_content function can be used to release it.

Another place to be aware of is the function return_size which allocates a temporary buffer and that buffer is leaked. What should happen is the return value of that function must be saved and then released (via free) after atoi is called. Actually, a much better option would be to change return_size to do what its name implies. It makes little sense to return a string in my opinion. That function should look like this :
C
int return_size( char* content )
{
    // allocating a buffer is unnecessary here, assuming a reasonably sized stack

    char string[ 100 ] = { 0 };  // initialize string to zeros
    int value = 0;
    int index = 0;
    int inside = 0;
    while( content[index] )
    {
        if( isdigit( content[ index ] )
        {
            string[inside++] = content[index];
        }
        index++;
    }
    value = atoi( string );
    return value;
}
Another improvement you can make is in take_name where a buffer of 18 characters is allocated. That also makes little sense when you could make file_name a character string of that size instead. Regardless, is a fixed-size buffer of 18 characters safe for all possible inputs? That seems unlikely to me so I would change your function to look like this :
C
char* take_name( int size, char** array )
{
//  using a call_name here is unnecessary because only the name is returned
//    call_name structure;
//    structure.size_inp = size;

    char * name = NULL;
    int y = 1;
    if( size > 0 )
    {
//       structure.file_name = (char*)malloc(sizeof(char)* 18);
//       structure.file_name = array[y];   // this will not work

        name = array[y];   // save a pointer to the file name argument
    }
    return name;  // return the pointer - will be null if no name specified
}
This allows you to accommodate a file name of any size supported by the OS and has the added benefit of not allocating any memory so no release is necessary.

Another thing - I recommend calling calloc instead of malloc because it clears the memory that is allocated - that's what the C stands for.

Lastly, if you use Visual Studio as your compiler it has memory tracking facilities built in so if you add this sequence in your code modules it will tell you where the leaks originate:
C++
#ifdef _DEBUG
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#endif
I do this in all my code to make certain it is free of leaks. If you do not use Visual Studio there are likely to be other mechanisms available.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900