Thread: regfree() failure

  1. #1
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    regfree() failure

    I wanted to write a function that would accept a string and a regular expression, then fill in a global struct with the beginning and end positions of a match, and return the actual match as another character string. Because regcomp() from regex.h only finds the first match in a line, I then wanted to use a static char copy of the original string which could be "blanked out" and matched against again to find multiple matches per line.

    As far as I can tell, something about including the static char causes regfree() to fail, such that regcomp acts like it's regmatch_t structure has not been freed from the last call (so matches nothing). I say this because an alternate version of the following script works fine (in which there is no static char in the "regexp_match" function, and the string to match must be "blanked out" before it is fed back into the function again. But I would prefer it to work this way and can't see what the problem is!
    Code:
    #include <stdlib.h> 
    #include <string.h>
    #include <regex.h>
    #include <stdio.h>
    
    char *chomp (char *line); // removes *nix newline from string
    char *regexp_match (char *string, char *regexp);
     
    struct matchspec {
    	int begin;
    	int end;
    } MSpec;
    
    
    int main () {
    	int i, count=1;
    	char input[164], *regexp, *string, *match;
    	
    	puts("character string:");
    	fgets(input,164,stdin);
    	string=chomp(input);
    
    	while (1) {
    		regexp = NULL;
    		puts("regular expression:");
    		fgets(input,164,stdin);
    		if (input[0] == '\n') return;
    		regexp=chomp(input);
    		printf("input: \"%s\" regexp: \"%s\"\n", string, regexp); 
    		if ((match=regexp_match(string,regexp)) != NULL) {
    	     		printf("%d -- B:%d E:%d is \"%s\"\n", count,MSpec.begin,MSpec.end,match); 
    				// retain value of static char in regexp_match by using NULL	
    			while ((match=regexp_match(NULL,regexp)) != NULL) {
    				count++;
    				printf("%d -- B:%d E:%d is \"%s\"\n", count,MSpec.begin,MSpec.end,match); 	
    			}
    		} else puts("No match.");
    		free(regexp);
    	}
    }
    
    
    char *chomp (char *line) {	// a standard function
    	int len, elen;
    	char *chompd, *end;
    	len = strlen(line);
    	end = strrchr(line,10);
    	if (end == NULL) return line;
    	else { 	elen = strlen(end);
    		if (elen > 1) return line;
    		else {	chompd = (char *)malloc(len-1);
    			strncpy(chompd,line,(len-1));
    			return chompd;
    		}
    	}
    }
    
    
    char *regexp_match (char *string, char *regexp) {
    	int i, w=0, len;
    	char *word = NULL;
    	static char *copy;
    	regex_t rgT;
    	regmatch_t match;
    	regcomp(&rgT,regexp,REG_EXTENDED);
    	if (string != NULL) {		// write "string" to the static char ("copy")
    		len=strlen(string);	// not needed in alternate version
    		copy=(char *)malloc(len+1);
    		strcpy(copy,string);
    	} 
    	if ((regexec(&rgT,copy,1,&match,0)) == 0) {
    		MSpec.begin = (int)match.rm_so;
    		MSpec.end = (int)match.rm_eo;
    		len = MSpec.end-MSpec.begin;
    		word=(char *)malloc(len+1);
    		for (i=MSpec.begin; i<MSpec.end; i++) {
    			word[w] = copy[i];
    			w++; }
    		word[w]=0;
    			// blank out match in "copy" for next call
    		for (i=MSpec.begin; i<MSpec.end; i++) {
    			copy[i]=32;}
    	}
    	regfree(&rgT); 	// DOESN'T WORK !!!
    	return word;
    }
    The output goes like this:
    Code:
    character string:
    the 6th one
    regular expression:
    th
    input: "the 6th one" regexp: "th"
    1 -- B:0 E:2 is "th"
    2 -- B:5 E:7 is "th"
    regular expression:
    th
    input: "the 6th one" regexp: "th"
    No match.
    Which actually means that regfree() worked the first time...it's not until "copy" is reinitialized with a new string that the problem begins.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Does the compiler not complain about this in main?
    Code:
    if (input[0] == '\n') return;
    You should return an integer in main...

    Sorry, I can't see anything directly wrong in your usage of regexp handling.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    regexec can find multiple matches in a string, look here for an example.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File I/O Assertion Failure in VS2008
    By clegs in forum C Programming
    Replies: 5
    Last Post: 12-25-2008, 04:47 AM
  2. Integer Emulation
    By Elysia in forum C++ Programming
    Replies: 31
    Last Post: 03-18-2008, 01:03 PM
  3. CreateWindow failure
    By TheDan in forum Windows Programming
    Replies: 6
    Last Post: 07-08-2005, 07:49 AM
  4. Am i a Failure?
    By Failure!!! in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 05-28-2003, 11:50 AM
  5. Assertion failure while creating window
    By roktsyntst in forum Windows Programming
    Replies: 0
    Last Post: 02-10-2003, 08:18 PM

Tags for this Thread