Link to home
Start Free TrialLog in
Avatar of flynny
flynnyFlag for United Kingdom of Great Britain and Northern Ireland

asked on

reading in file memory problems in vc++ 6

hi, i'm having problems with my program.

i'm reading in a file which contains information which is added into my structure. If i read the file in once it works fine. However if i try and read in the same or another file it crashes giving a user break called from code exception. I also get an access violation if i open a file and then exit the program (whether these are related i'm not sure).

anyway, using break points i tracked the point of the exception being thrown to here

addButton(tHook, tText, tClass, tX, tY, tWidth, tHeight, tAnchor, tProgram, tOutput, tFields);

this method doesn;t get called and according to the debug all the CString vars are filled.  These are global vars that i reuse every time i read a file in.

CString tHook, tClass, tText, tOutput, tProgram;
int tAnchor, tX, tY, tWidth, tHeight;
int tFields[maxFields];

i simply assign the string token to the CString like so                   
tClass = token;


Avatar of cruxy
cruxy

hm. could you please give more input?

Especially what type is a token? Are you sure, that you want to overwrite tClass?
Avatar of flynny

ASKER

yes sorry,

the way i read in my files i i read it in a line at a time (i determine this using a terminator ';')

so for example i then have

WINDOW=TestWindow

i then use strtok to split the string using = as a separator.
LPTSTR token;
...
//get line
token = strtok( line, seps );
if(strcmp(token, "WINDOW") == 0)
{
token = strtok( NULL, seps );
tClass = token;
}

yes i will want to overwrite these each time as i copy them into the structure. i just hold these so i can call the addButton method when i have all the variables.  

One thing i forgot to mention also before i read the file in i remove everything from the current structure, using a method initialiseStructure. I have just tried removing this and this seems to sort allow me to open the file again (although it adds everything twice). is there somthing wrong with what i do here?

BOOL initialiseStructure()
{
      GlobalFree(debug);
      GlobalFree(hookFile.executable);
      GlobalFree(hookFile.title);

      int i;
      for(i=0; i<maxHooks; i++)
      {
            if(hookFile.hooks[i] == NULL)
                  break;

            GlobalFree(hookFile.hooks[i]->window);
            
            int j;
            for(j=0; j<maxButtons; j++)
            {
                  if(hookFile.hooks[i]->buttons[j] == NULL)
                        break;

                  GlobalFree(hookFile.hooks[i]->buttons[j]->bClass);
                  GlobalFree(hookFile.hooks[i]->buttons[j]->text);
                  
                  hookFile.hooks[i]->buttons[j]->dimensions->x = NULL;
                  hookFile.hooks[i]->buttons[j]->dimensions->y = NULL;
                  hookFile.hooks[i]->buttons[j]->dimensions->width = NULL;
                  hookFile.hooks[i]->buttons[j]->dimensions->height = NULL;
                  hookFile.hooks[i]->buttons[j]->dimensions->anchor = NULL;
                  GlobalFree(hookFile.hooks[i]->buttons[j]->dimensions);

                  GlobalFree(hookFile.hooks[i]->buttons[j]->output);
                  GlobalFree(hookFile.hooks[i]->buttons[j]->program);
                  
                  int k;
                  for(k=0; k<maxFields; k++)
                  {
                        if(hookFile.hooks[i]->buttons[j]->fields[k] == NULL)
                              break;

                        GlobalFree(&hookFile.hooks[i]->buttons[j]->fields[k]->fieldPath);
                        GlobalFree(hookFile.hooks[i]->buttons[j]->fields[k]);
                  }

                  GlobalFree(hookFile.hooks[i]->buttons[j]);
            }

            GlobalFree(hookFile.hooks[i]);
      }

      return true;
}
first thing,  GlobalFree() is probably the wrong thing to call.  That's an old windows 3.1  API.

If you allocated a node with a C++ "new", you should  use the corresponding C++ "delete".

If you allocated memory with "malloc", you should call "free".

Also it looks like you're generating pointers with strtok().  Don't try freeing those pointers!   They're not pointing to anything that was allocated on the heap, so these free's are going to blow up.

ASKER CERTIFIED SOLUTION
Avatar of cruxy
cruxy

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of flynny

ASKER

hi thanks for the reply.

i'm using globalalloc to allocate the memory for each item e.g.

            BUTTON *pBut = (BUTTON*) GlobalAlloc(GPTR, sizeof(BUTTON));

            HGLOBAL memPtr = GlobalAlloc(GMEM_FIXED, strlen(bClass)+1); //pointer to mem block

            if( memPtr && (pBut->bClass = (LPTSTR)GlobalLock(memPtr)) != NULL )
                  RtlMoveMemory(pBut->bClass, bClass, strlen(bClass)+1);
            else
            {
                  char buf[128];
                  sprintf(buf, "Error Unable to allocate Memory for button class.");
                  MessageBox(NULL, buf, NULL, 0);
            }

also this is how i read my line before i use strtok

                  ch = fgetc(fr);
                  charCount = 0; //reset

                  while(ch != ';') //read to find out what the type is
                  {      
                        line[charCount] = ch;

                        charCount++;
                        ch = fgetc(fr);

                        if(charCount > lineSize)
                              return -5;

                        if(ch == EOF)
                        {                              
                              fclose(fr);
                              return 0; //read ok
                        }

                  }
                  line[charCount] = '\0';
also regards the pointers should i simply set these to null?

many thanks
Avatar of flynny

ASKER

hi bu changing the GlobalFree(ptr) to just setting them to NULL solved this problem.

However the other problem with the access violation on after i open a file and then close the program still arises. it then points to this line

1020E761   mov         dword ptr [ecx],edx

does this look like it is something to do with not cleaning the mem up?
You should not be allocating objects, if that's what bClass is, with anything other than the C++ "new"!!  
Avatar of flynny

ASKER

ok the problem is i need other objects in the process to see these objects, will that still be the case with new?

so rather than

BUTTON *pBut = (BUTTON*) GlobalAlloc(GPTR, sizeof(BUTTON));

will

BUTTON *pBut = new BUTTON();

suffice? then can i simply assign the CStrings to the variables in the structure?
many thanks matt
the new would allocate the object as it should happen, so calling the constructor.
this has nothing todo with the CString problematic. cause a CString is only direct castable as a LPCTSTR; you need a LPTSTR instead, so you should call tClass.getBuffer(strlen(token)+1) then copy over the string from token with strcpy() and then calling tClass.ReleaseBuffer() after that point the buffer is only accessible via the tclass methods; the pointer got with getBuffer should not be used anymore.