memory leak

Discussion in 'Mac Programming' started by dougphd, Oct 21, 2016.

  1. dougphd macrumors member

    Joined:
    Apr 28, 2016
    #1
    When I run my code through Analysis, I get that there is a potential memory leak pointed to by path.
    I don't see it. Anybody?

    Code:
    get_index_and_open(FILE * listp)
    
    {
    
    char           *filename, *path;
    
    filename = (char *)calloc(75, sizeof(char));
    
    path = (char *)calloc(75, sizeof(char));
    
    if ((fscanf(listp, "%s", filename)) != 1) {
    
    return (NULL);
    
    } else {
    
    strcpy(path, home);
    
    strcat(path, filename);
    
    if ((datap = fopen(path, "r")) == NULL) {
    
    printf("Couldn't open index file\n");
    
    } else {
    
    printf("opened data file %s\n", filename);
    
    fscanf(datap, "%s", filename);
    
    }
    
    }
    
    free(filename);
    
    free(path);
    
    return (datap);
    
    }
    /[code]
     
  2. mif, Oct 21, 2016
    Last edited: Oct 21, 2016

    mif macrumors regular

    Joined:
    Feb 16, 2010
    Location:
    home
    #2
    Code:
    if ((fscanf(listp, "%s", filename)) != 1)
    {
        return (NULL);
    }
    
    if fscanf returns a value different from one, code does not free allocated memory?
     
  3. dougphd thread starter macrumors member

    Joined:
    Apr 28, 2016
    #3
    goof guess but no
    Code:
    if ( (fscanf(listp,"%s",filename)) != 1)
    
        {
    
            free (filename);
    
            free (path);
    
            return (NULL);
    
            }
    /[code]
     
  4. cqexbesd macrumors regular

    Joined:
    Jun 4, 2009
    Location:
    Germany
    #4
    Once adding in those extra frees the analyser doesn't complain about anything for me.

    Maybe you can post your code in a compilable form, along with an indication of the line that the analyser is complaining about.
     
  5. Senor Cuete macrumors 6502

    Joined:
    Nov 9, 2011
    #5
    Your code is difficult to read because of all of the double spacing.
     
  6. dougphd thread starter macrumors member

    Joined:
    Apr 28, 2016
    #6
    Here's the latest code and files that should help in testing for those are willing. The location of an EXC_BAD_ACCESS is noted in ID.h I get this : Declared variable-length array (VLA) has zero size (within a call to 'read_data_to_struct') when I run analyze.
    main.c
    Code:
    int main(int argc, const char * argv[]) {
        int num_of_indices;
        listp = open_symbol_list();
        datap = get_index_and_open(listp);
        num_of_indices = -1;
        while (datap != NULL)
       {
        num_of_indices++;
        read_data_to_struct(datap, num_of_indices);
        datap = get_index_and_open(listp);
       }
    }
    /[code]
    ID.h
    [code]
    
    #define list_of_indices "/Users/douglasbrenner/ANDY/DATA/data_files/files.txt"
    #define home  "/Users/douglasbrenner/ANDY/DATA/data_files/"
    #define days_of_data 60000
    #define last_date "20161007"
    #define first_date "20061006"
    FILE *listp, *datap;
    
    typedef struct
    {
        char name[20][days_of_data];
        char date[14][days_of_data];
        float close[days_of_data];
        int num[days_of_data];
    }stock_index;
    
    typedef  stock_index *indx;
    
    indx read_data_to_struct(FILE *datap, int num_of_indices)
    {
     int j;
      char *line,*junk,*word;
     line = (char*)calloc(100,sizeof(char));
     junk = (char*)calloc(1,sizeof(char));
    word = (char*)calloc(10,sizeof(char));
    indx  I[num_of_indices];
     if ((I[num_of_indices] = (stock_index*)calloc( 1, sizeof(stock_index)))== NULL)
         printf("didn't allocate memory %d", num_of_indices);
     j = 0;
     do   {
            fscanf(datap,"%s\n",line);
            strcpy(I[num_of_indices]->name[j],strtok(line,","));//symbol
            strcpy(junk,strtok(NULL,","));
           [B] strcpy(I[num_of_indices]->date[j],strtok(line,","));//date   ERROR HERE[/B]
             j++;
    }
        while( (strcmp(first_date,I[num_of_indices]->date[j-1])) != 0);  //  printf(" %s %s\n",I[num_of_indices]->name[j-1],I[num_of_indices]->date[j-1] );
    
        fclose(datap);
        free(line);
        free(junk);
        free(word);
        return (I[num_of_indices]);
    
    }
    
    
    FILE * get_index_and_open(FILE * listp)
    
    {
    
        char *filename,*path;
        filename = (char *) calloc(75,sizeof(char));
        path = (char *) calloc(75,sizeof(char));
       if ( (fscanf(listp,"%s",filename)) != 1)
       {
           free (filename);
            free (path);
          return (NULL);
            }else{
           strcpy(path,home);
            strcat(path,filename);
           if ((datap = fopen(path,"r")) == NULL)
              {
                  printf("Couldn't open index file\n" );
            }else{
               printf("opened data file %s\n", filename);
                fscanf(datap,"%s",filename); //read header line
            }
          }
      free (filename);
       free (path);
        return (datap);
       }
    FILE * open_symbol_list()
    
    {
       if ((listp = fopen(list_of_indices,"r")) == NULL)
       {
            printf("Couldn't open list of indices\n" );
            exit(0);
        }
    
    return(listp);
    }
    /[code]
    --- Post Merged, Oct 22, 2016 ---
    You are right. Is there an easy way to remove the second line return? They are added by the forum
    --- Post Merged, Oct 22, 2016 ---
    The line in ID.h where the error occurs should read
    strcpy(I[num_of_indices]->date[j],strtok(NULL,","));//date
    but the error is still the same.
     

    Attached Files:

  7. robvas macrumors 68030

    Joined:
    Mar 29, 2009
    Location:
    USA
    #7
    Here's a tip. You already know the size of your character arrays, so don't bother with dynamically allocating memory for them

    line = (char*)calloc(100,sizeof(char));

    becomes char line[100];

    As a bonus you know don't have to worry about a memory leak. If you didn't know the size of the string or you were going to change the amount of memory it was using, you could use malloc()
     
  8. chown33, Oct 22, 2016
    Last edited: Oct 22, 2016

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    Location:
    Sailing beyond the sunset
    #8
    Suppose you define an array like this:
    Code:
    int foo[ 3 ];
    How many items can you safely store into it?

    What is the highest safe index?


    Next, consider this array:
    Code:
    int foo[ 0 ];
    Same questions.


    So, given that you are in fact passing 0 to read_data_to_struct(), please explain exactly what do you expect to happen with this array definition?
    Code:
    indx  I[num_of_indices];
    Furthermore, if num_of_indices is more than 0, say 12, explain exactly what you expect to happen with expressions like this:
    Code:
    I[num_of_indices]->name[j]
    In other words, answer the question, "What is the highest safe index?", given the declaration of the length of the array I.


    I'll also note that the array I is always and only referenced as I[num_of_indices]. If you're only ever referencing a single item in an array, then you can use a simple scalar variable — you don't need an array.

    The variable num_of_indices is always and only used to index the array I. This serves no practical purpose.

    If there's a reason for I being an array in this code, it's not apparent. So not only is the code semantically broken (array size and max safe index), but the rationale for using an array at all, or even having num_of_indices, is nowhere to be seen.

    What is the purpose of I being an array?
    What is the purpose of num_of_indices in the function, if I isn't an array?


    There's more that's wrong with read_data_to_struct(). For example, it returns a calloc'ed memory block, but the caller doesn't keep it, so that block is being leaked.


    In general, I've found that if someone can't explain what the code they wrote is expected to do, then insufficient thought went into it.

    If one is confused about what one wants to achieve, or about how to achieve it, then the code will also be confused. The error then lies in the problem-solving thought process, not just the translation of that solution into code. In short, confused problem-solving yields confused code.

    Conversely, if a concise and correct explanation can be given, but the code doesn't reflect that, then the error often lies in an inadequate understanding of how to translate the description into code. That's a very different problem than confusion in the problem-solving process.
     
  9. dougphd thread starter macrumors member

    Joined:
    Apr 28, 2016
    #9
    Some one had suggested that I not hard code the number of indices in a #define num_of_indices. Therefore I tried to allocate memory one I at a time - the bracket meant to indicate which I not how many. Obviously, I see what I did. Why I (not I) try to figure out how to do this, it would be great if you would give me a clue or the answer.
    Thanks.
     
  10. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    Location:
    Sailing beyond the sunset
    #10
    Speaking for myself, I can't give you a clue or an answer, because I don't know one.

    I don't know what you're trying to accomplish.

    I can't infer what you want to accomplish by reading the code, because the code is broken and confused. I can describe what the code does, but it makes no sense. I can't infer anything sensible from nonsense.

    I can't tell you how to code what you want from a description, because you haven't provided a description of what you want to accomplish.
     
  11. dougphd thread starter macrumors member

    Joined:
    Apr 28, 2016
    #11
    It seems so transparent to me. lol

    There is a list of symbols which I open. I get a symbol (for an index) which (maybe not so obviously) is a text file.
    Then I open the text file which contains my data; which I then read it into a structure. I do this again and again until there I reach the end of the list.
    My immediate problem is allocating memory for the data containing structures.
    Code:
     
    listp = open_symbol_list();
    
      datap = get_index_and_open(listp);
    
        num_of_indices = -1;
    
        while (datap != NULL)
    
        {
    
        num_of_indices++;
    
        read_data_to_struct(datap, num_of_indices);
    
        datap = get_index_and_open(listp);
    
        }
    /[code]
     
  12. robvas macrumors 68030

    Joined:
    Mar 29, 2009
    Location:
    USA
    #12
    Look how easy this is to do in python. Put this code in a file called 'doug.py' in the same folder that your text files are in

    Code:
    import csv # we need this to read the CSV files
    
    input_file = '_10GSPCW.TXT'
    stock_index = []
    
    with open(input_file, 'rb') as f:
        reader = csv.reader(f)
        for row in reader:
            stock_index.append(row)
    
    print stock_index[0]
    print stock_index[1]
    print stock_index[300]
    
    Spend Sunday (or Monday and Tuesday evening) going through this tutorial and you'll find yourself getting things much faster than you would ever imagine with C - https://learnpythonthehardway.org/book/

    You can do a lot with Python and financial data

    https://github.com/twiecki/financial-analysis-python-tutorial
     
  13. dougphd thread starter macrumors member

    Joined:
    Apr 28, 2016
    #13
    F*K python. and ruby too for that matter. I don't care if the code is one line. they are slow; and compile at run time right?
     
  14. robvas macrumors 68030

    Joined:
    Mar 29, 2009
    Location:
    USA
    #14
    How are they slow? You aren't processing terabytes of data.
     
  15. dougphd thread starter macrumors member

    Joined:
    Apr 28, 2016
    #15
    what makes you think that a code snippet to load data is all there is? what happens if after running code for an hour or two a runtime complier spots because of a typo. save your breath
     
  16. Red Menace macrumors 6502

    Red Menace

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #16
    As already mentioned, unless you are processing massive amounts of data, "slow" is a subjective term. There are native machine compilers for both Python and Ruby - note that most implementations these days compile to bytecode that can be interpreted or just-in-time compiled. Both languages can also use C/C++ libraries (and are themselves usually written in C), so again, depending on what exactly you are doing, they are not that slow.

    Higher level languages do tend to make the process of developing an application faster, simpler, and more understandable, along with reducing the number of forum topics about language semantics.

    Good luck with your windmill.
     
  17. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    Location:
    Sailing beyond the sunset
    #17
    What makes you think a separate compiler is immune to such errors?

    As your own code trivially demonstrates, code can compile but not run correctly. If that's in a section of code that isn't reached until after an hour or two, then you still have the same ultimate problem.


    FWIW, the usual way of working to avoid problems like this is to test the code with known data, giving known results. You then employ coverage testing, that tells you which parts of the code were executed and which parts weren't. If there's some code that wasn't executed, you devise additional tests to ensure it gets executed.

    However, no testing will find all possible errors. This is true for all forms of code, in all languages.
     

Share This Page