Advertisement

ANSI C Memory Allocation Nightmare!

Started by June 01, 2001 09:23 AM
2 comments, last by kharris 23 years, 8 months ago
All right guys, I am really lost in my efforts to solve a problem. Here is the rundown. I am writing a program to parse through a file, read the files formatted input into records. I plan on making the records an array. So, my strategy was to run through the file, keeping track of how many records I have gotten so far, and use that number to index into my array of records. Also, the end of the file is denoted by the first character being 0. The code is listed below. Now let me explain my problem. In the beginning of every iteration of the main while(!feof) loop, after the fscanf statement, whatever is read into the string line is also placed in every record's strings[0] spot up to the numRecords upper bound. Also, after the tokenization, line, as well as the strings[0]'s all contain the first token retrieved. I know it's kind of complicated, but I think that my problem is a simple one which lies in my memory allocation. It seems that everything I save in any of my pointers just writes over all of the other ones. If anyone is interested in actually trying to debug, I can email the whole program and input file. Thanks for any help.

typedef struct _record {
 int  amount;
 char *strings[4];
} record;

/*
 Declarations & Initializations.
*/

char *token;
char *line;

record *file;
record *tempRecord;

char filename[25] = "example.txt";

int howmany      = 0;
int i            = 0;
int j            = 0;
int counter      = 0;
int numRecords   = 0;
int recordNumber = 0;
int found        = 0;
int fileDone     = 0;

FILE *infile;

/*
 Begin of main program.
*/
int main() {

 /*
  Initialize memory.
 */
 line              = (char *)malloc(100 * sizeof(char));
 token             = (char *)malloc(20 * sizeof(char));
 file              = (record *)calloc(10, sizeof(record));

 /*
  Initialize memory for file records.
 */
 for (k=0; k<10; k++) {
    for (j=0; j<4; j++) {
       file[k].strings[j] = (char*)malloc(20 * sizeof(char));
    }
 }

 infile = fopen(filename, "r");
 if (infile == NULL) {
  printf("File, %s, could not be opened.\nExiting...\n\n", filename);
  exit(1);
 }
 /*
  Loop which parses through the lines of the file.
 */
 while (!feof(infile)) {
  if(fscanf(infile, "%d,%s", &howmany, line)) {
   if (howmany != 0) {
    if (numRecords < 10) {
     token = strtok(line, ",");
     /*
      Fill in the first record in the record[] file.
     */
     file[numRecords].amount     = howmany;
     file[numRecords].strings[0] = token;
     /*
      This loop uses the number read to pull out the
      desired number of tokens.
     */
     for (j=1; j   

Edited by - kharris on June 1, 2001 10:30:49 AM

Edited by - kharris on June 1, 2001 10:35:17 AM

Edited by - kharris on June 1, 2001 10:37:22 AM

Edited by - kharris on June 1, 2001 10:39:31 AM    
I think your problem is that your are not COPYING the string that you get from token into your allocated string buffers.

You are doing this:

strings[j] = token; // bad bad bad!

Assigning the token pointer to strings[0] just sets strings[0] to contain the address of token (pointer assignment). On the next call to fscanf, all the token pointers pointing into ''line'' become invalidated and change!

You need to copy the token string into your buffer:

strcpy(strings[j], token, strlen(token));

I think this is your problem. Anywhere you do a strings[x] = token assignment, you need to replace that with a string copy (strcpy())

BTW, if you were using std::string (C++) the assignment strings[j] = token would work


Take care,



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com
Advertisement
Well, that worked. Thanks a lot Dire Wolf!
No problem



Dire Wolf
www.digitalfiends.com
[email=direwolf@digitalfiends.com]Dire Wolf[/email]
www.digitalfiends.com

This topic is closed to new replies.

Advertisement