Thread: Finding memory leaks

  1. #1
    Registered User
    Join Date
    Sep 2014
    Posts
    2

    Angry Finding memory leaks

    Hi! This is my first post here but I am sure not the last one hah. I am still newbie when it comes to programming - my first year learning it during studies.

    The programme itself takes the every word from file and counts how often does every word occur. It works fine, but I keep on struggling to find, where are the memory leaks. I still get 106 allocs and 27 frees here.

    I have to do it using linear search and the function of 'structure' type which will return structure with number of occurances of certain word and the actual word.

    Sorry for messy post like this, I will make other posts more organized.

    Code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    
    
    typedef struct{
        char* word;
        int count;
    }Structure;
    
    
    Structure* words;
    int arraySize;
    int endOfFile;
    
    
    FILE *openFile(char *fileName);
    void closeFile(FILE *fp, char *fileName);
    char *getWord(FILE *fp);
    Structure * findWord(char* word);
    int linearSearch(Structure* pointer, int size, char* find);
    
    
    int main(int argc, char *argv[]) {
        if(argc == 2) { /*check input syntax; requires 2 items ./name infile*/
            int i = 0;
            char* word;
            Structure* foundWord;
            FILE *input = openFile(*(argv + 1));
            arraySize = 0;
            word = getWord(input);
            while(!endOfFile){
                if (word != NULL){
                    foundWord = findWord(word);
                    if(foundWord == NULL){
                        arraySize++;
                        words = realloc(words, arraySize * sizeof(Structure));
                        words[i].word = malloc((strlen(word) + 1) * sizeof(char));
                        strcpy (words[i].word, word);
                        words[i].count = 1;
                        i++;
                    }else{
                        (*(foundWord)).count++;
                    }
                    free(word);
                }
                word = getWord(input);
            }
            free(word);
            for ( i = 0 ; i < arraySize; i++ ){
                printf("%s - %d\n", words[i].word, words[i].count);
            }
            for ( i = 0; i < arraySize; i++ ){
                free( words[i].word );
            }
            free( words );
            closeFile(input, *(argv + 1));
        }
        else {
            printf("Incorrect invocation of %s\n", *argv);
            exit(EXIT_FAILURE);
        }
        return 0;
    }
    
    
    FILE *openFile(char *fileName) { /*handles file opening*/
        FILE *fp;
        if((fp = fopen(fileName, "r")) == NULL) {
            printf("Cannot open file: %s\n", fileName);
            exit(EXIT_FAILURE);
        }
        else {
            printf("FILE OPENED\n");
        }
        return fp;
    }
    
    
    void closeFile(FILE *fp, char *fileName) { /*handles file closing*/
        if(fclose(fp) == EOF) {
            printf("Error closing file: %s\n", fileName);
            exit(EXIT_FAILURE);
        }
        else {
            printf("FILE CLOSED\n");
        }
    }
    
    
    char *getWord(FILE *fp) {
        char *savedString = NULL, *tmp = NULL;
        size_t size = 0, index = 0;
        int scanBuffer = EOF;
        while(scanBuffer) {
            scanBuffer = fgetc(fp);
            if (scanBuffer == EOF && savedString == NULL){
                endOfFile = 1;
                return NULL;
            }
            if(!isalpha(scanBuffer)) {
                scanBuffer = 0;
                break;
            }
            if(size <= index) {
                size += sizeof(char);
                if((tmp = realloc(savedString, size)) == NULL) {
                    printf("MEMORY ERROR\n");
                }
                if(!tmp) {
                    free(savedString);
                    savedString = NULL;
                    break;
                }
                savedString = tmp;
            }
            savedString[index++] = tolower(scanBuffer);
        }
        if(savedString != NULL){
            size += sizeof(char);
            if((tmp = realloc(savedString, size)) == NULL) {
                printf("MEMORY ERROR\n");
            }
            if(!tmp) {
                free(savedString);
                savedString = NULL;
            }
            savedString = tmp;
            savedString[index++] = '\0';
        }
        return savedString;
    }
    
    
    Structure * findWord(char* word){
        int position;
        position = linearSearch (words, arraySize, word);
        if (position == -1){
            return NULL;
        }
        return &words[position];
    }
    
    
    int linearSearch(Structure *pointer, int size, char* find){
        int i;
        for ( i = 0 ; i < size ; i++ ){
            if (strcmp( (*(pointer + i)).word, find) == 0){
                return i;
            }
        }
        return -1;
    }
    Easy come, easy go, will you let me go?
    Bis-mil-lah !
    No, we will not let you go. (Let him go)
    Bis-mil-lah !
    We will not let you go. (Let me go)
    Bis-mil-lah !
    We will not let you go. (Let me go)
    Will not let you go. (Let me go)
    Will not let you go. (Let me go)

    Ah.
    No, no, no, no, no, no, no (Oh mamma mia, mamma mia)
    Mamma mia, let me go.
    Belzebub has a devil put aside for me, for me, for me.
    For example for text file above you get:

    FILE OPENED
    easy - 2
    come - 1
    go - 13
    will - 6
    you - 6
    let - 12
    me - 9
    bis - 3
    mil - 3
    lah - 3
    no - 8
    we - 3
    not - 5
    him - 1
    ah - 1
    oh - 1
    mamma - 3
    mia - 3
    belzebub - 1
    has - 1
    a - 1
    devil - 1
    put - 1
    aside - 1
    for - 3
    FILE CLOSED

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Where did you get the information from that there were leaks?

    Code:
    $ valgrind ./a.out bar.c
    ==4643== Memcheck, a memory error detector
    ==4643== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
    ==4643== Using Valgrind-3.6.1-Debian and LibVEX; rerun with -h for copyright info
    ==4643== Command: ./a.out bar.c
    ==4643== 
    FILE OPENED
    include - 4
    stdio - 1
    h - 4
    stdlib - 1
    string - 1
    ctype - 1
    typedef - 1
    struct - 1
    char - 17
    word - 18
    int - 13
    count - 4
    structure - 8
    words - 12
    arraysize - 7
    endoffile - 3
    file - 14
    openfile - 3
    filename - 7
    void - 2
    closefile - 3
    fp - 9
    getword - 4
    findword - 3
    linearsearch - 3
    pointer - 3
    size - 10
    find - 3
    main - 1
    argc - 2
    argv - 4
    if - 15
    check - 1
    input - 5
    syntax - 1
    requires - 1
    items - 1
    name - 1
    infile - 1
    i - 20
    foundword - 4
    while - 2
    null - 13
    realloc - 3
    sizeof - 4
    malloc - 1
    strlen - 1
    strcpy - 1
    else - 4
    free - 6
    for - 3
    printf - 8
    s - 4
    d - 1
    n - 8
    incorrect - 1
    invocation - 1
    of - 1
    exit - 6
    failure - 3
    return - 8
    handles - 2
    opening - 1
    fopen - 1
    r - 1
    cannot - 1
    open - 1
    opened - 1
    closing - 2
    fclose - 1
    eof - 3
    error - 3
    closed - 1
    savedstring - 14
    tmp - 7
    t - 1
    index - 4
    scanbuffer - 7
    fgetc - 1
    isalpha - 1
    break - 2
    memory - 2
    tolower - 1
    position - 4
    strcmp - 1
    FILE CLOSED
    ==4643== 
    ==4643== HEAP SUMMARY:
    ==4643==     in use at exit: 0 bytes in 0 blocks
    ==4643==   total heap usage: 2,328 allocs, 2,328 frees, 68,467 bytes allocated
    ==4643== 
    ==4643== All heap blocks were freed -- no leaks are possible
    ==4643== 
    ==4643== For counts of detected and suppressed errors, rerun with: -v
    ==4643== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
    $
    It seems nice and clean to me.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Sep 2014
    Posts
    2
    Ow man... <facepalm> I was using valgrind on the .C file instead of a.out.
    valgrind ./task.c
    Now I see I had to do it differently with ./a.out
    Sometimes I am suprised how stupid I can be... And it is not the first time I couldn't notice wrong compilation...
    Thank you very much Sir and sorry for taking your time

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 6
    Last Post: 10-15-2012, 05:16 PM
  2. tools for finding memory leaks
    By mvenkata in forum C++ Programming
    Replies: 0
    Last Post: 05-24-2010, 02:53 PM
  3. tools for finding memory leaks
    By stanlvw in forum C++ Programming
    Replies: 4
    Last Post: 04-03-2009, 11:41 AM
  4. Memory usage and memory leaks
    By vsanandan in forum C Programming
    Replies: 1
    Last Post: 05-03-2008, 05:45 AM
  5. Memory leaks
    By Malek in forum C++ Programming
    Replies: 2
    Last Post: 02-09-2003, 06:12 PM