Thread: Str_replace function

  1. #1
    Registered User
    Join Date
    Jul 2004
    Posts
    68

    Str_replace function

    Ive been creating my own extended string library one of the functions is a str_replace function.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char *str_replace(char *find, char *replacement, const char *string);
    
    int main()
    {
    	char string[] = "Testing String Testing String String test string";
    	char *newString = str_replace("Testing","test",string);
    	char *newString2 = str_replace("string", "", newString);
    	
    	printf("String: \t\t%s\nNew String: \t\t%s\nNew String 2: \t\t%s\n", string, newString, newString2);
    	
    	free(newString);
    	free(newString2);
    	return 0;
    }
    
    char *str_replace(char *find, char *replacement, const char *string)
    {
    	char *ptr, *newString, *compString, *restOfString;
    	int findLength = 0, position = 0, endPosition = 0;
    	
    	int i; /* for loop */
    	
    	/* String Lengths and Difference */
    	findLength = strlen(find);
    	
    	/* Allocate Memory for compString */
    	if ((compString = malloc(strlen(string) + 1))==NULL)
    	{
    		fprintf(stderr, "Memory Allocation Error");
    		exit(1);
    	}
    	strcpy(compString,string);
    	
    	/* Allocate 1 char for null character for newString (used to return the new string */
    	if ((newString = malloc(1))==NULL)
    	{
    		fprintf(stderr, "Memory Allocation Error");
    		exit(1);
    	}
    
    	/* Find and Replace all Strings */
    	while (compString != NULL) /* Set to Null incase we find a substring on the end of the string */
    	{
    		/* Find Substr */
    		if ((ptr=strstr(compString, find))!=NULL)
    			position=ptr-compString;
    		else
    		{
    			/* Why ?
    				Cos there is possibly more on the string we need to return the entire string with the find strings replaced
    			*/
    			if ((newString = realloc(newString, strlen(newString) + strlen(compString) + 1))==NULL)
    			{
    				fprintf(stderr, "Memory Allocation Error");
    				exit(1);
    			}
    			
    			/* Concatenate the end of the string */
    			strcat(newString, compString);
    			
    			/* Free compString */
    			free(compString);
    			return newString; /* All Possible strings to be found have been we need to kill this loop */
    		}
    		
    		if (position != 0)
    		{
    			if ((restOfString=malloc(position))==NULL)
    			{
    				fprintf(stderr, "Memory Allocation Error");
    				exit(1);
    			}
    		
    			/* Copy the String to restOfString before finding the substr */
    			for (i=0;i<=position;i++)
    				(restOfString)[i]=(compString)[i];
    			(restOfString)[position]='\0';
    			
    			/* Allocate Memeory for restOfString for newString */
    			if ((newString = realloc(newString, strlen(newString) + strlen(restOfString) + strlen(replacement) + 1))==NULL)
    			{
    				fprintf(stderr, "Memory Allocation Error");
    				exit(1);
    			}
    			
    			/* Concatenate restOfString onto newString */
    			strcat(newString, restOfString);
    			free(restOfString);
    		}
    		
    		/* Reallocate Memory to newString */
    		if ((newString = realloc(newString, strlen(newString) + strlen(replacement) + 1))==NULL)
    		{
    			fprintf(stderr, "Memory Allocation Error");
    			exit(1);
    		}
    		/* Concatenate new String */
    		strcat(newString, replacement);
    		
    		/* Delete from found onwards */
    		endPosition = position + findLength;
    		(compString) = (ptr+strlen(find));
    	}
    	
    	free(compString);
    	return newString;
    }
    The first use of this function on the same string works correctly, however use the same string and function again and I get a seg fault error. Now it could be that im freeing wrong things or something and I simply cannot find where it is.

  2. #2
    Unregistered User
    Join Date
    Nov 2004
    Posts
    25
    Strange... I tried your program in my compiler (Dev-cpp 4.9.9.0) and I don't get any seg fault...

  3. #3
    Registered User
    Join Date
    Jul 2004
    Posts
    68
    Ive seemed to have found it

    Code:
                /* Free compString */
                free(compString);
                return newString; /* All Possible strings to be found have been we need to kill this loop */
    However remove the free(compString); and the next time str_replace is used there are still garbage characters around.

  4. #4
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    First of all, your function name imposes on your compiler's namespace. According to the C standard you're not permitted to name anything starting with "str".

    Secondly, it's generally a better idea to pass a buffer to the function rather than have the function allocate memory and then trust the caller to free it. I think I'd rewrite the str_replace() function so the prototype looked something like:
    Code:
    char *replace_str(const char *string, const char *find, const char *replacement, char *buf, int maxlen);
    There's a reason you never see a standard string function allocate memory for you. It's easy to forget to free memory that you don't allocate yourself.
    If you understand what you're doing, you're not learning anything.

  5. #5
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by gsoft
    Ive seemed to have found it


    However remove the free(compString); and the next time str_replace is used there are still garbage characters around.
    Here's a way to debug something like this:

    Since you have more-or-less located an anomaly, see what you are malloc'ing and what you are free'ing:

    Code:
        if ((compString = malloc(strlen(string) + 1))==NULL)
        {
            fprintf(stderr, "Memory Allocation Error");
            exit(1);
        }
        printf("After malloc(): compString = %p\n", compString);
        strcpy(compString,string);
    and

    Code:
                /* Free compString */
                printf("Before free(): compString = %p\n", compString);
                free(compString);
    Hmmm. Time for a re-think? (Red flag when set a pointer to an allocated region and change the value before free.)

    Regards,

    Dave

  6. #6
    Registered User
    Join Date
    Jul 2004
    Posts
    68
    Ive decided to redo the function and do Memory Allocation within the function. The new prototype is

    Code:
    char *replace_str(char *find, char *replacement, const char *string, char *destination, size_t size);
    Now destination pointer will be allocated prior to being sent to the replace_str function.

    e.g.
    char test[100];

    So 100 bytes have been allocated for test which will be sent as the destination parameter. Is it possible to then reallocate memory using realloc if the string becomes bigger than 100 bytes

    Code:
    if ((destination=realloc(destination, size + strlen(string) + 1))==NULL)
    {
      //error here
    }
    Since im guessing destination since it hasnt be given a value and has garbage characters, its produces a segfault when using realloc.

    This is what the str_replace function now replace_str funciton looks like now, its incomplete.

    Code:
    char *replace_str(char *find, char *replacement, const char *string, char *destination, size_t size)
    {
    	char *ptr, *tempString;
    	int findLength = 0;
    	
    	/* Gather Find String Details */
    	findLength = strlen(find);
    	
    	/* Allocate Memory for string and copy */
    	if ((tempString = malloc(strlen(string) + 1))==NULL)
    	{
    		fprintf(stderr, "Memory Allocation Error");
    		exit(1);
    	}
    	strcpy(tempString, string);
    	
    	return NULL;
    }

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by gsoft
    char test[100];

    So 100 bytes have been allocated for test which will be sent as the destination parameter. Is it possible to then reallocate memory using realloc if the string becomes bigger than 100 bytes
    No, you can't realloc an array.

    This old thread may be of interest.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    Registered User
    Join Date
    Jul 2004
    Posts
    68
    Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  3. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM