Thread: funcion runs 14 times, then program crashes

  1. #1
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391

    funcion runs 14 times, then program crashes

    Hey all.

    The aim of this program gets a string that doesn't contain the word "every", breaks up the string into 2 strings, appends "every" onto the first string, then appends the second string onto the first(modified string).

    Here's the compilable code.

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #define FILELINELENGTH 1000		
    #define NUMBEROFFILES 1000		
    #define FILENAMELENGTH 100	
    
    #define STRING1LENGTH 200
    #define STRING2LENGTH 600
    
    void insertstring(void);
    char *p_searchtext = " every ";		// string to search for in a file
    FILE *p_openfile;
    char *p_line1;
    
    int main(void)
    { 	
    	struct data {
            char storefilename[FILENAMELENGTH];		
    		char filename1[FILENAMELENGTH];			
    		char filename2[FILENAMELENGTH];			
        } LineData[NUMBEROFFILES];
    
    	int lastfilenumber1, lastfilenumber2;
    	char *p_line;						
    	char *p_newline;
        int  counter;						
    	int	 counter1 = 0;					
    	int	 counter2 = 0;					
    	char *p_searchstring;
    							
    	system("dir /b c:\\testwebsite\\*.html > directorylisting.txt");
    
        if((p_openfile = fopen("directorylisting.txt", "rt")) == NULL)
        {
            perror("directorylisting.txt");
            exit( EXIT_FAILURE );
        } 
        counter = 0;
    
    	// Copy the filenames from the file to the array; replace the newline character with a terminating
    	// null character to make it a string which can be opened by fopen().
    
        while((fgets(LineData[counter].storefilename, FILENAMELENGTH, p_openfile) != NULL) && (counter < NUMBEROFFILES))
    	{
    		if((p_newline = strchr(LineData[counter].storefilename, '\n')) != NULL)
    			*p_newline = '\0';
    
            counter++;	
    		lastfilenumber1 = counter;
        }
        fclose(p_openfile);
    
    	if((p_line = malloc(FILELINELENGTH * sizeof(char))) == NULL )
    	{
    		perror("Error allocating memory");
    		exit (EXIT_FAILURE);
    	}
    
    	// Open up a file, search for p_searchtext, if it exists, store filename(LineData[counter].storefilename)
    	// in LineData[counter2].filename1. Open up next file etc.
    
    	for( counter = 0; counter < lastfilenumber1; counter++) 
    	{	
    		int found = 0;
    		if((p_openfile = fopen(LineData[counter].storefilename, "r")) == NULL)
    		{
    			printf("error opening file: %s", LineData[counter].storefilename);
    			exit(EXIT_FAILURE);
    		}
    
    		while((fgets(p_line, FILELINELENGTH, p_openfile)) != NULL) 	//// search string found
    		{
    			if((p_searchstring = strstr(p_line, p_searchtext) != NULL))
    			{
    				strcpy(LineData[counter1].filename1, LineData[counter].storefilename);
    				found = 1;
    				counter1++;
    				break;
    			}
    		}
    
    		if(!found) // search string NOT found
    		{
    			strcpy(LineData[counter2].filename2, LineData[counter].storefilename);
    			rewind(p_openfile);
    			insertstring();
    			counter2++;
    		}
    		fclose(p_openfile);
    	}
    	free(p_line);
    
    	printf("\nThere are %d files containing the search string\n", counter1);
    	printf("\nThere are %d files NOT containing the search string\n", counter2);
    
        return 0;
    }
    
    void insertstring(void)
    {
    	char *p_searchstring = "lists";
    	char storestring[FILELINELENGTH];
    	char string1[STRING1LENGTH];
    	char string2[STRING2LENGTH];
    	char *location;
    	int cursorposition;
    	int counter = 0;
    
    	while((fgets(storestring, FILELINELENGTH, p_openfile)) != NULL) 	
    	{
    		if((location = strstr(storestring, p_searchstring)) != NULL) 
    		{
    			cursorposition = location - storestring;
    			break;
    		}
    	}
    
    	memmove(string1, storestring, cursorposition+5);  // 5 is to allow space for the string "lists"
    	string1[cursorposition+5] = '\0';
    	strcat(string1, p_searchtext);
    
    	for(counter = (cursorposition+5); storestring[counter] != '\0'; counter++)	
    		string2[counter - (cursorposition+5)] = storestring[counter];   // copy string into the start of string2
    
    	string2[counter - (cursorposition+5)] = '\0';
    	strcat(string1, string2);
    	printf("%s", string1);
    }
    When I run this program in debugger, after the insertstring runs 14 times, the program crashes. A debugger window pops up with:
    Unhandled Exception at 0x7c90e8b6(ntdll.dll) in testing.exe: 0xC0000005: Access violation writing location 0x00030ffc
    When I click the "break" button, another window pops up with:
    There is no source code available for the current location
    And then there is a button to "Show Disassembly", but I don't know what that does.

    Can anyone offer a guess as to why the program would behaviour in this manner?

    Thanks in advance.

    PS: I've made some variables global because I am experimenting with variable scope.

    Indentation Disclaimer
    Sometimes weird translation happens when I post my code from VC++ 2008 into a forum thread. The indentations are magnified by an order of magnitude, which pushes the code far to the right of the screen. My indentation is good, but the weird translation makes it look bad. It's not my fault. Honest.
    Last edited by happyclown; 03-03-2009 at 09:38 PM.
    OS: Linux Mint 13(Maya) LTS 64 bit.

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    It's compilable, but I have no "dir" command and I have no c:\testwebsite directory.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    One potential problem is this:

    Code:
        int cursorposition;
        int counter = 0;
    
        while((fgets(storestring, FILELINELENGTH, p_openfile)) != NULL) 	
        {
    	if((location = strstr(storestring, p_searchstring)) != NULL) 
    	{
    	    cursorposition = location - storestring;
    	    break;
    	}
        }
    
        memmove(string1, storestring, cursorposition+5);  // 5 is to allow space for the string "lists"
    You do not initialize cursorposition to 0. Instead, you rely on entering into the while(), and then the if(), at the top of the block. But suppose p_openfile is at EOF -- you will NOT enter the while(), yet you will continue on and do a memmove() using cursorposition+5, and since cursorposition is not initialized, it explodes.

    Do you happen to have 14 files in that directory?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Sorry for the triple post, but sometimes people don't see my edits.

    The fact that it's crashing inside ntdll.dll is also informative. It's not your code which is crashing per se but some system function, which you've probably passed a bad pointer to. That should narrow down the number of places it could be.

    If you install Microsoft's Windows debugging symbols, it would show you what function was actually crashing.

    Try popping up a few levels in the debugger until you get back into your code.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Thanks for your help, brewbuck.

    Quote Originally Posted by brewbuck View Post

    But suppose p_openfile is at EOF -- you will NOT enter the while(), yet you will continue on and do a memmove() using cursorposition+5, and since cursorposition is not initialized, it explodes.
    Right before I call the function insertstring(), I use rewind(p_openfile), to reset the position back to the start. At least, that's what my intention.

    Do you happen to have 14 files in that directory?
    I have 621 files, but I expect the function to process 84 files that don't contain the word "every".

    The funny thing is, when I run this program in the console, it prints to the screen(as it should), but when I try to redirect the output with

    Code:
    testing > output.txt
    the output file is empty(blank). That's weird.

    Here is a typical string that the function will process:
    <META NAME="Description" CONTENT="This page lists tranceiver by case shape, voltage, size, weight, number of bands, price and model number.">
    The function inserts every after the word "lists".

    I supposed if you really want to run the program, you could put the above string into a file, save the file as 1.html, 2.html....15.html. Then put the files into a directory called "testwebsite".

    Then you can probably run your debugger on it.

    And this is the output in the call "stack window."
    > ntdll.dll!__SEH_prolog() + 0xb bytes
    ntdll.dll!_RtlLookupFunctionTable@12() + 0x7d bytes
    ntdll.dll!_RtlIsValidHandler@4() + 0x29 bytes
    ntdll.dll!_RtlDispatchException@8() + 0x79 bytes
    ntdll.dll!_KiUserExceptionDispatcher@8() + 0xe bytes
    OS: Linux Mint 13(Maya) LTS 64 bit.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    If we can't read your posts, it doesn't matter whose fault it is.

    Indentation Disclaimer
    Sometimes weird translation happens when I post my code from VC++ 2008 into a forum thread. The indentations are magnified by an order of magnitude, which pushes the code far to the right of the screen. My indentation is good, but the weird translation makes it look bad. It's not my fault. Honest.
    Since the forum may not change anytime soon, you need to change your indenting. The way I did it was to change from using a tab, to using 3 spaces of the space bar per indent.

    Looks good, and never runs off the forum page. (I scowl at it if it tries)

    You may also have an option for the editor to insert spaces, instead of a tab, even though you're pressing the tab. Just tell it how many spaces you want it to substitute for the tab, and you're off and running. This didn't work for me, but it might with your editor/IDE.

    Good luck!

  7. #7
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Thanks for the tip, Adak!
    OS: Linux Mint 13(Maya) LTS 64 bit.

  8. #8
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Quote Originally Posted by brewbuck View Post

    You do not initialize cursorposition to 0.
    Quote Originally Posted by brewbuck View Post
    Try popping up a few levels in the debugger until you get back into your code.

    Hey, I've just initialized cursorposition to 0, and now the loop runs fine 14 times(outputs 14 strings), then outputs "every l" 8 times, then outputs 15 more strings.

    And then this message came up in the debugger:
    Code:
    Run-Time Check Failure #2 - Stack around the variable 'string1' was corrupted.
    And then I keep pressing continue and similar error messages(for other variables ie. "storestring") pop-up, and then the function prints out more output, and then more error messages, and then more ouput.

    Here's the total number of error messages that popped up:
    Code:
    Run-Time Check Failure #2 - Stack around the variable 'string1' was corrupted.
    Run-Time Check Failure #2 - Stack around the variable 'string1' was corrupted.
    Run-Time Check Failure #2 - Stack around the variable 'storestring' was corrupted.
    Run-Time Check Failure #2 - Stack around the variable 'storestring' was corrupted.
    Run-Time Check Failure #2 - Stack around the variable 'string1' was corrupted.
    Run-Time Check Failure #2 - Stack around the variable 'storestring' was corrupted.
    Run-Time Check Failure #2 - Stack around the variable 'string1' was corrupted.
    Run-Time Check Failure #2 - Stack around the variable 'storestring' was corrupted.
    The program '[1416] testing.exe: Native' has exited with code 0 (0x0).
    So now, heaps of the files I expected to be processed by the function are being processed(way more than 14).

    I think you were onto something with that initialization of cursorposition, brewbuck!
    Last edited by happyclown; 03-03-2009 at 10:45 PM.
    OS: Linux Mint 13(Maya) LTS 64 bit.

  9. #9
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    so now you have a buffer (probably string1) which is way too small for storing your string

    check the length of the source before copying it to destination
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  10. #10
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Quote Originally Posted by vart View Post
    so now you have a buffer (probably string1) which is way too small for storing your string
    Yep, that was it.

    I increased the storage size of string1, and now the program runs without crashing.

    Thanks for everybody's help!
    OS: Linux Mint 13(Maya) LTS 64 bit.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Utter newb?: Program crashes after input
    By deductible in forum C++ Programming
    Replies: 5
    Last Post: 12-13-2008, 10:27 PM
  2. Program crashes, why?
    By Mahdi123 in forum C Programming
    Replies: 5
    Last Post: 04-18-2007, 02:56 PM
  3. Scheduling Algo
    By BigDaddyDrew in forum C++ Programming
    Replies: 41
    Last Post: 03-08-2003, 11:00 AM
  4. Replies: 5
    Last Post: 08-05-2002, 07:14 PM
  5. multiple runs of a program
    By unregistered in forum Linux Programming
    Replies: 5
    Last Post: 03-15-2002, 07:18 AM