Thread: Calling free() causes program crash

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    6

    Question Calling free() causes program crash

    Hi All,
    I come across this weird issue when using free() and malloc(). The oringinal work is with YACC and LEX. I extract some code from it to show what the problem is.
    There are three tokens to be processed by function dummy(int index):
    Code:
            char* yytext_c = "anotherword";
    	char* yytext_a = "signed";
            char* yytext_b = "thelongestofall";
    function dummy(int index) compares the last token name read with some constant string, and then saves the current token in 'last_name'. Its only argument 'index' tell it which token (yytext_a or yytext_b or yytext_c) to process.
    'last_name' is declared and intialized as:
    Code:
    static char* last_name=NULL;
    so that it may be re-used the next time dummy is called.

    The logic seems simple (spot any errors?). However, the execution crashes. By tracing its execution, the program crashes at this line:
    Code:
      free(last_name);
    I am not posting the error message depends on the programming environment and run-time library.
    There are ways to avoid the crash as I figured out today, but i do not really understand:
    - in branch 1, 2 and 3, if we comment out this line
    last_name[i] = '\0';
    the program will run smoothly.

    - if we change the initial value of the three tokens, e.g.:
    Code:
               char* yytext_b = "anotherword";
    	    char* yytext_c = "signed";
               char* yytext_a = "thelongestofall";
    we too may avoid the crash.

    I run out of ideas after screw around for several hours. Any suggestions on what went wrong?


    thanks a lot.

    tony
    --------------------------------------
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
        char* yytext_c = "anotherword";
        char* yytext_a = "signed";
        char* yytext_b = "thelongestofall";
    
        void dummy(int index){
    	        static char* last_name=NULL;
    		int len,i;
                    char* t1 = "signed";
    		char* t2 = "unsigned";
    
    		if (last_name!=NULL)
    				   printf("******* last token = %s \n", last_name);
    
    		if (last_name!=NULL && strcmp(last_name,t1)!=0 && strcmp(last_name,t2)!=0)
    					  printf("--- rule 1.1.15 --- violated --- \n");
    
    		if( last_name != NULL )
    				 {
    				     free(last_name);
    				 }
    
    
    		if (index==0)    // branch 1, save yytext_a
    				   {   len = strlen(yytext_a)+1;
    				   	last_name =(char*) malloc(len*sizeof(char));
    				   	for (i=0; i<len; i++){
    				   	  last_name[i] = yytext_a[i];
    				        }
    
    				    last_name[i] = '\0';
    				   }
    				 if (index==1)   // branch 2,  save yytext_b
    				   {  len = strlen(yytext_b)+1;
    				       last_name =(char*) malloc(len*sizeof(char));
    				       for (i=0; i<len; i++){
    				          last_name[i] = yytext_b[i];
    				        }
    				       last_name[i] = '\0';
    
    				    }
    
    				  if (index>1)  // branch 3, save yytext_c
    			           {
    				      len = strlen(yytext_c)+1;
    				      last_name =(char*) malloc(len*sizeof(char));
    				      for (i=0; i<len; i++){
    					  	last_name[i] = yytext_c[i];
    					  }
    				      last_name[i] = '\0';
    				     }
    		 }
    
    int main(){
          int j = 0;
          int limit = 5;
          while (j<limit) {
    		    dummy(j);
    		    j++;
          }
         return(0);
    	}
    Last edited by casmac; 06-12-2010 at 07:06 AM.

  2. #2
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Code:
    	len = strlen(yytext_a)+1;  // len is including null byte here 
    	   	for (i=0; i<len; i++){  
    
                   }
       	      last_name[i] = '\0';  // i = len here valid indices[0-strlen(yytext_a)]
    and your indentation sucks. Improve it.
    Last edited by Bayint Naung; 06-12-2010 at 05:05 AM.

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    6
    Quote Originally Posted by Bayint Naung View Post
    Code:
    	len = strlen(yytext_a)+1;  // len is including null byte here 
    	   	for (i=0; i<len; i++){  
    
                   }
       	      last_name[i] = '\0';  // i = len here valid indices[0-strlen(yytext_a)]
    I am trying to build a C string that terminated with '\0'.
    and strlen(x) returns the length that excludes the terminating '\0'.
    I still do not see your point. Could you be more detailed?

  4. #4
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    Code:
    				   {  
                                         len = strlen(yytext_b)+1;   // take note len include null byte
    				       last_name =(char*) malloc(len*sizeof(char));
    				       for (i=0; i<len; i++){             // now loop copies also null byte
    				          last_name[i] = yytext_b[i];
    				        }
    				       last_name[i] = '\0';          
     //  if you allocate strlen() + 1, valid indices to last_name [0-strlen()] .
    // just like a[N]   0 to N-1 are valid indices.
    Take note that len holds the string length plus one for null byte.
    When you do the copying, you already copied the null byte. Why not use strcpy/memcpy?
    When the loop breaks, the value of i is len which is strlen(yytext_b)+1 which is not valid index to last_name.
    and you are writing '\0' to that location.
    Last edited by Bayint Naung; 06-12-2010 at 07:26 AM.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    6
    Quote Originally Posted by Bayint Naung View Post
    Take note that len holds the string length plus one for null byte.
    When you do the copying, you already copied the null byte. Why not use strcpy/memcpy?
    When the loop breaks, the value of i is len which is strlen(yytext_b)+1 which is not valid index to last_name.
    and you are writing '\0' to that location.
    you are right!! How did I mess this up?
    THank you for your help.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Because you didn't check that you were writing to a valid index. Always do that. It's fine even if you put in asserts to notify you if such a mistake should occur.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C program crash... I'm stumped.
    By Dino in forum C Programming
    Replies: 7
    Last Post: 03-16-2008, 08:27 AM
  2. Calling delete Crashes my Program
    By thetinman in forum C++ Programming
    Replies: 19
    Last Post: 10-13-2007, 03:07 AM
  3. How to avoid console program crash when terminated too early
    By Xargo in forum A Brief History of Cprogramming.com
    Replies: 6
    Last Post: 10-03-2007, 04:43 PM
  4. Using variables in system()
    By Afro in forum C Programming
    Replies: 8
    Last Post: 07-03-2007, 12:27 PM
  5. Replies: 3
    Last Post: 03-04-2005, 02:46 PM

Tags for this Thread