Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

dougphd

macrumors member
Original poster
Apr 28, 2016
70
0
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]
 
Code:
if ((fscanf(listp, "%s", filename)) != 1)
{
    return (NULL);
}

if fscanf returns a value different from one, code does not free allocated memory?
 
Last edited:
goof guess but no
Code:
if ( (fscanf(listp,"%s",filename)) != 1)

    {

        free (filename);

        free (path);

        return (NULL);

        }
/[code]
 
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.
 
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]
[doublepost=1477145216][/doublepost]
Your code is difficult to read because of all of the double spacing.
You are right. Is there an easy way to remove the second line return? They are added by the forum
[doublepost=1477148526][/doublepost]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.
 

Attachments

  • _10GSPCW.TXT
    38.1 KB · Views: 270
  • _10TRGSW.TXT
    39.6 KB · Views: 261
  • files.txt
    17.4 KB · Views: 272
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()
 
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.
 
Last edited:
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.
 
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.
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.
 
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]
 
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
 
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?
 
How are they slow? You aren't processing terabytes of data.
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
 
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?
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.
 
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
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.
 
  • Like
Reactions: jaduff46
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.