2

My code has a memory leak problem. I don't know where I went wrong. Below is the code: I am trying to read from csv file and store a particular columns.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
    FILE *result = fopen ("C:\\Users\\pa1rs\\Desktop\\local.csv", "w");

    const char *text = "LOA,NAME,";
    fprintf (result, "%s", text);
    char *token;
    char *endToken;
    int lines = 0;
    char ch;                            /* should check the result */
    FILE *file = fopen ("C:\\Users\\pa1rs\\Desktop\\samplee.csv", "r");
    char line[300];
    if (file == NULL) {
        perror ("Error opening the file");
    } else {
        while (!feof (file)) {
            ch = fgetc (file);
            if (ch == '\n') {
                lines = lines + 1;
            }
        }
        //printf(" no of lines existing in the file %d\n\n", lines);
    }
    fseek (file, 0, SEEK_SET);
    while ((ch = fgetc (file)) != '\n') {
        // we don't need the first line on sample.csv
        // as it is just the description part
    }
    int s[lines - 1];
    int j = 0;
    char *N[lines - 1];
    while (fgets (line, sizeof (line), file)) {
        int i = 0;
        token = line;
        do {
            endToken = strchr (token, ',');
            if (endToken)
                *endToken = '\0';
            if (i == 3) {
                s[j] = atoi (token);
            }
            if (i == 12) {
                N[j] = (char *) malloc (strlen (token) * sizeof (char));
                strcpy (N[j], token);
            }

            if (endToken)
                token = endToken + 1;
            i++;
        } while (endToken);
        j = j + 1;
    }
//******************************************************unigue loa
    int count = 0;
    int g = 0;
    int h = 0;
    int LOA[lines - 1];
    int dd = 0;
    for (dd = 0; dd < lines - 1; dd++) {
        LOA[dd] = 0;
    }
    for (g = 0; g < lines - 1; g++) {
        for (h = 0; h < count; h++) {
            if (s[g] == LOA[h])
                break;
        }
        if (h == count) {
            LOA[count] = s[g];
            count++;
        }
    }
    int xw = 0;
    for (xw = 0; xw < count; xw++) {
        //printf("%d \t",LOA[xw]);
    }

    //printf("LOA Array Length is: %d \n",count);


    //********************************************************
    ////FOR UNIQUE NAMES ARRAY


    //printf("No of unique names are %d",county);
    //FOR UNIQUE CAUSES ARRAY
    char *sa[9] =
        { "Monticello", "Valparaiso", "Crown Point", "Plymouth", "Goshen",
"Gary", "Hammond", "Laporte", "Angola" };
    int countz = 0;
    int gz = 0;
    int hz = 0;
    char *LOAz[lines - 1];
    int zero2 = 0;
    for (zero2 = 0; zero2 < lines - 1; zero2++) {
        LOAz[zero2] = NULL;
    }
    for (gz = 0; gz < lines - 1; gz++) {
        for (hz = 0; hz < countz; hz++) {
            if (strcmp (N[gz], LOAz[hz]) == 0)
                break;
        }
        if (hz == countz) {
            LOAz[countz] = (char *) malloc (strlen (N[gz]) * sizeof (char));
            strcpy (LOAz[countz], N[gz]);
            countz++;
        }
    }
    int nz = 0;
    for (nz = 0; nz < countz; nz++) {
        fprintf (result, "%s,", LOAz[nz]);
    }
    fprintf (result, "\n");
    // printf("%d",countz);
    //*****************************
    int i = 0;
    int jjj = 0;
    int xxx = 0;
    int ggg = 0;
    int k = 0;
    int kount[count][countz];
    for (xxx = 0; xxx < count; xxx++) {
        for (ggg = 0; ggg < countz; ggg++) {
            kount[xxx][ggg] = 0;
        }
    }
    for (i = 0; i < count; i++) {
        for (k = 0; k < countz; k++) {
            for (jjj = 0; jjj < lines - 1; jjj++) {
                if (LOA[i] == s[jjj]) {
                    if (strcmp (LOAz[k], N[jjj]) == 0) {
                        kount[i][k]++;

                    }
                }

            }
        }
    }

    int ig = 0;
    int ik = 0;
    for (ig = 0; ig < count; ig++) {
        fprintf (result, "%d,%s", LOA[ig], sa[ig]);
        for (ik = 0; ik < countz; ik++) {
            fprintf (result, ",%d", kount[ig][ik]);
        }
        fprintf (result, "\n");
    }
    int rrr = 0;
    free (N);
    for (rrr = 0; rrr < lines - 1; rrr++) {
        free (LOAz[rrr]);
    }

    //*****************************
    //fclose(result);
    fclose (file);
    return 0;
}

Lines I got here is 13761 and LOAz was declared with array size lines-1=13761, but unique ones I got here are only 49, So I am reallocating memory for that and remaining are unused , I think problem started there. Please help! Thanks in Advance.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
Yashwanth Potu
  • 346
  • 4
  • 19
  • To trace down memory leaks you want to use memory checker like Valgrind (https://valgrind.org). – alk Feb 05 '16 at 13:49
  • You fail to close `result` after you open with `FILE *result = fopen`. Assuming `rrr` loops over `countz` in `LOAz[countz]`, then the failure to close the file is your only leak. Also, please organize your declarations. You should generally declare your variables at the beginning of each block of code, not in ad-hoc sprinklings throughout each block. – David C. Rankin Feb 05 '16 at 14:06

1 Answers1

1

One problem in your code is that you don't allocate enough memory for strings. For example, in these lines:

N[j] = (char*) malloc(strlen(token) * sizeof(char));
strcpy(N[j], token);
// ...
LOAz[countz] = (char*) malloc(strlen(N[gz]) * sizeof(char));
strcpy(LOAz[countz], N[gz]);

The problem is that strlen returns the number of non-zero symbols in the string. However, to store the string you need one more byte, to also store the zero terminating character, so the buffer size to store s should be at least strlen(s) + 1.

Also, a better coding style is to avoid casting the return value of malloc.

Community
  • 1
  • 1
kfx
  • 8,136
  • 3
  • 28
  • 52