Thread: Big problems with the Text function

  1. #1
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669

    Unhappy Big problems with the Text function

    Hi!

    I have huge problems with this (Text) function and the strlen function. When I use them together the exception is thrown when I run the program in the DEBUG configuration manager. In the RELEASE c.m. everything is OK.

    Code:
    # define STPFILE "setup.cfg"
    
    typedef struct
    {
        char LanguageFile[30];
     } Setup;
    
    char *ReadLanguage () // function reads a language file from the file "setup.cfg"
    {
        FILE *fin = NULL;
        Setup file;
    
        if ((fin = fopen (STPFILE, "rb")) != NULL)
        {
            fread (&file, sizeof (Setup), 1, fin);
    	fclose (fin);	
    	return file.LanguageFile;
        }
        else return NULL;
    }
    
    char *Text (char File[], short Line)
    {
        FILE *fin = NULL;
        short Lines = 0, UC = 0;
        char Character, *Text1 = NULL, *temp = NULL;
    
        if ((fin = fopen (File, "rt")) != NULL)
        {
            Text1 = malloc (sizeof (char) * 100);
    	if (Text1 == NULL) exit (1);	
            temp = Text1;
    	while (fscanf (fin, "%c", &Character) != EOF)
    	{
    	    if (Character == '#') Lines++; // counting lines
    	    if (Lines == Line)
    	    {
    	        if (Character != '\n')
    		{
    		    UC++;
    		}
    		if (UC >= 8)
    		{
    		    if ( (Character == ';') || (Character == '\n') ) break;
    		    *(temp++) = Character;
    		}
    	    }
            }
            *temp = 0;
            fclose (fin);
            return Text1;
        }
        else
        {
            return NULL;
        }
    }
    Text and strlen function together:
    Code:
    char *Text1 = Text (ReadLanguage (), 1); // functions "Text" and ReadLanguage() are called.
    // Function Text reads the first line in the "ReadLanguage ()" file
    short Text1Length = (short) strlen (Text1) + 1; <- here is thrown the exception
    This is what I get in .NET:
    " Unhandled exception at 0x00419d10 in Text.exe: 0xC0000005: Access violation reading location 0x00000000. "

    But when I use strlen in a different way, something like this, everything is OK (in the DEBUG c.m.).
    Code:
    short Text1Length = 0;
    Text1Length = (short) strlen ("HELLO") + 1; <- the exception is not thrown
    What could be wrong? Is it the Text function?
    I would be very grateful for your answers.
    I'm using Visual Studio C++.NET on Win2k.
    Last edited by GaPe; 05-22-2002 at 03:48 AM.
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Access violation reading location 0x00000000
    You probably dereferenced NULL

    Looking at your code, there's lots to choose from

    My guess, is it will ultimately track back to

    > fread (&file, sizeof (Setup), 1, fin);

    This is almost certainly wrong if setup.cfg is a text file
    1. It will have a newline in it, unless your filename is exactly 30 chars long
    2. In any event, there's no \0 to mark the end of the string

    Which leads to
    > if ((fin = fopen (File, "rt")) != NULL)
    failing because of the junk filename

    etc....

  3. #3
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669
    I tried to print out the file that it reads from the setup.cfg file and it came out that it is null. But this only happens when I have a DEBUG c.m. In the RELEASE c.m. I get the file printed on the screen (it's not the junk filename). I looked the options of the DEBUG but I have all the directorys well written. I really don't get it. And Salem, the file "setup.cfg" is a binary file.
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  4. #4
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Like Salem, said your probably referencing a pointer that is NULL. I'd suggest using the poor mans debugger (printf), and print out the value of some of the pointers your passing around. Then play Spot The NULL One In The Wrong Place.

    use printf like this:
    >printf ("ptr is %p", ptr);

    Also, you said the file is binary, but you opened it with "rt".
    Last edited by Hammer; 05-19-2002 at 08:33 AM.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  5. #5
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669
    The file "setup.cfg" is binary. The path to the file which is written in the "setup.cfg" file is a text file and it is opened with mode "rt".

    EDIT:

    Why is everything OK when I run the program in the RELEASE c.m?
    Last edited by GaPe; 05-19-2002 at 09:27 AM.
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  6. #6
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Suggest putting a printf here:
    Code:
    ....
     }
        else
        {
            printf("File Open Failed! %s\n", File); /* <--- put this in */
            return NULL;
            }
    }
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  7. #7
    ....
    Join Date
    Aug 2001
    Location
    Groningen (NL)
    Posts
    2,380
    Take a closer look at this:

    Code:
    char *Text1 = Text (ReadLanguage (), 1);
    The problem may be there, since function ReadLanguage can return NULL.

    And you cannot do this in function Text:

    Code:
    Text1 = malloc (sizeof (char) * 100);
    That is because of this:

    Code:
    char *Text1 = Text (ReadLanguage (), 1);
    In the function Text you have to declare a temporary variable, allocate memory for it and return the pointer.

    You have to declare and allocate a new piece of memory and return the pointer of that.

    Code:
    char *tempText = malloc (sizeof (char) * 100);
    ..
    return tempText;

  8. #8
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669
    Can anyone explain to me WHY is the program working when I run it as a RELEASE??
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  9. #9
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    does it run from 2 different directories?
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Can anyone explain to me WHY is the program working when I run it as a RELEASE??
    It usually means you have a bug of some sort

    Which when compiled using different compiler flags (eg optimisation), either covers up (or in this case uncovers) a bug.

  11. #11
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Shiro:
    >You have to declare and allocate a new piece of memory and return the pointer of that
    Isn't that being done here:
    Code:
            Text1 = malloc (sizeof (char) * 100);
    	if (Text1 == NULL) exit (1);	
            temp = Text1;
    	while (fscanf (fin, "%c", &Character) != EOF)
    	{
    	    if (Character == '#') Lines++; // counting lines
    	    if (Lines == Line)
    	    {
    	        if (Character != '\n')
    		{
    		    UC++;
    		}
    		if (UC >= 8)
    		{
    		    if ( (Character == ';') || (Character == '\n') ) break;
    		    *(temp++) = Character;
    		}
    	    }
            }
            *temp = 0;
            fclose (fin);
            return Text1;
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  12. #12
    ....
    Join Date
    Aug 2001
    Location
    Groningen (NL)
    Posts
    2,380
    You're correct. I didn't see that Text1 was also a local variable within the function.

    >if (Text1 == NULL) exit (1);

    Don't use exit (1) here, but return NULL. Because then you can check Text1 in your other function. If it is NULL, something wrong happened.

    >*temp = 0;

    Try to change this to

    *temp = '\0'

    which is usually used to end a string.

    >short Text1Length = (short) strlen (Text1) + 1;

    That may be the reason of a failure here. Not sure about that, but you could try it. If I am correct then strlen expects a string which ends with '\0'.

    Put some printf's in your code to trace what the functions do, where they exit, why they exit etc.

  13. #13
    Registered User Azuth's Avatar
    Join Date
    Feb 2002
    Posts
    236
    As to the why, it sounds like a Mandelbug, I'm surprised this hasn't been posed by Prelude, who I'm sure has "C Unleashed" memorized.

    "The program works 70% of the time (for given inputs), or only works outside the debugger...."

    It goes onto describe this type of bug as "the reverse of the Heisenbug". These it appears are usually memory violations... "either some pointer is pointing somewhere it shouldn't, or some array index is wrong"

    I know this probably doesn't tell most of the readers of this thread anything they don't already know, but I found the read interesting, and I love trivia. Anyhow, a possible answer would be, that when your debugger is running, the memory your code allocates is unsafe, but when your debugger isn't running, the memory your program allocates is safe. A very untrustworthy situation long term.
    Demonographic rhinology is not the only possible outcome, but why take the chance

  14. #14
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669
    This bug is a pain in the ass. Do the strncpy, strcpy and strcat functions add the '\0' at the end of the string?

    Now I'm trying with printf's to detect the bug but I just can't find it. Anyone knows how to use the debugger in the .NET studio?
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  15. #15
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Based on your code in your first post:
    Code:
    #define STPFILE setup.cfg
    
    typedef struct 
    {
    	char	LanguageFile[30];
    } Setup;
    
    char *ReadLanguage(void);
    char *Text(char[] , short);
    
    /* */
    char *ReadLanguage(void)	// function reads a language file from the file "setup.cfg"
    {
    	FILE	*fin = NULL;
    	Setup	file;
    	if ((fin = fopen(STPFILE, "rb")) != NULL)
    	{
    	.........................
    The bold parts don't work, because you haven't surrounded the filename in quotes. The compiler preprocessor will resolve this to
    >if ((fin = fopen(setup.cfg, "rb")) != NULL)
    which is incorrect, it should be
    >if ((fin = fopen("setup.cfg", "rb")) != NULL)

    So to resolve, change to #define to
    >#define STPFILE "setup.cfg"
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  2. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  3. structure vs class
    By sana in forum C++ Programming
    Replies: 13
    Last Post: 12-02-2002, 07:18 AM
  4. Ok, Structs, I need help I am not familiar with them
    By incognito in forum C++ Programming
    Replies: 7
    Last Post: 06-29-2002, 09:45 PM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM