Thread: memory problem with string manipulation

  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    31

    memory problem with string manipulation

    I'm terrible when it comes to string manipulation, I always seem to find a way to segfaut or something. I'm trying to return the string between 2 offsets of another string but I'm getting weird results for what should be a simple function.

    Code:
    char* substr( char *searchstr, int offset1, int offset2 ){
          int size = offset2-offset1;
          char tmpstr[size];
          int m = 0;
          for( int i = offset1; i < size; i++ ){
               tmpstr[m] = searchstr[i];
               m++;
          }
          char *str;
          str = (char*)malloc( sizeof( char ) * size );
          strcpy( str, tmpstr );
          return str;
    }
    Everything seems to work perfectly, however when I tried substr("wonderful", 0, 5) the returned result was "wonde +B" which leads me to believe I'm doing something wrong with the memory.

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Last edited by Dave_Sinkula; 07-09-2005 at 01:16 AM.
    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.*

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    31
    Ahh, of course.. Thanks champ.

  4. #4
    Registered User
    Join Date
    Sep 2004
    Posts
    31
    Still doesn't seem to be working properly, the output is not always correct. Sometimes it will just output the char 's' and there wasn't a single one in the given string.. Any ideas? I've modified the code slightly-

    Code:
    char* substr( char *searchstr, int offset1, int offset2 ){
          int size = offset2-offset1;
          char tmpstr[size];
          int m = 0;
          for( int i = offset1; i < size; i++ ){
               tmpstr[m] = searchstr[i];
               m++;
          }
          char *str;
          str = (char*)malloc( sizeof( char ) * size + 1 );
          strcpy( str, tmpstr );
          str[size] = '\0';
          return str;
    }
    I just don't understand how this is happening.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    hmm... shouldnt it be more like:
    Code:
    char* substr(char* searchstr, int offset1, int offset2) {
    	char* tempstr = new char[offset2-offset1+2];
    	int i = 0, j = offset1;
    	while (j <= offset2) {
    		tempstr[i++] = searchstr[j++];
    	}
    	return tempstr;
    }
    with the idea of using offset2-offset1+2 as b-a+1 gives the number of integers in range [a,b], adding 1 to account for '\0'
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Sep 2004
    Posts
    31
    Alright. Well now for the next problem. I'm trying to use that function with the following to return string between 2 delimiters.
    Code:
    char* strbetween( char* searchstr, char* delimiter1, char* delimiter2 ){
         char* str;
         int offset1 = -1;
         int offset2 = -1;
         int lendel1 = strlen( delimiter1 );
         int lendel2 = strlen( delimiter2 );
         int lensrch = strlen( searchstr );
         for( int i = 0; i < lensrch; i++ ){
              if( i+lendel1 < lensrch ){
                  if( strcmp( delimiter1, substr( searchstr, i, i+lendel1 ) ) == 0 ){
                      offset1 = i+lendel1+1;
                      break;
                  }
              }
         }
         for( int i = 0; i < lensrch; i++ ){
              if( i+lendel2 < lensrch )
                  if( strcmp( delimiter2, substr( searchstr, i, i+lendel2 ) ) == 0 ){
                      offset2 = i-1;
                      break;
                  }
         }
         if( offset1 > 0 && offset2 > 0 )
             str = substr( searchstr, offset1, offset2 );
         else
             str = NULL;
         return str;
    }
    [edit:] Umm.. the actual problem is, it always returns NULL.
    Last edited by Ichmael™; 07-09-2005 at 05:12 AM.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Pretend that this function exists:
    Code:
    //returns index of 1st character of substring in haystack that matches needle
    //returns -1 if needle not found in haystack
    int findStr(char* haystack, char* needle);
    So one just uses findStr() on searchstr and delimiter1.
    If the index returned is not -1, then offset1 is set to the sum of the index returned and the length of delimiter1.
    Then one uses findStr() on searchstr and delimiter2.
    If the index returned is not -1, then offset2 is set to 1 less than the index.
    We then use substr() on the offsets, perhaps after a check that offset1 <= offset2.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Sep 2004
    Posts
    31
    Ahh I have this problem of making things unecesseraily complicated. I'll see how I go with that, but I can see the idea is much more logical.
    Last edited by Ichmael™; 07-10-2005 at 02:26 AM.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    hmm... I decided to give implementing strbetween a try since I have so little experience with the C string functions.
    Here's my version:
    Code:
    #include <iostream>
    #include <cstring>
    
    //returns substring of searchstr between delimiter1 and delimiter2
    char* strbetween(char* searchstr, char* delimiter1, char* delimiter2) {
    	//start of delimiter1 in searchstr
    	//named betw as it contains substring to be returned
    	char* betw = strstr(searchstr, delimiter1);
    	//check that delimiter1 is found
    	if (betw == 0) {
    		return 0;
    	}
    	//start of delimiter2 in searchstr
    	char* after_betw = strstr(searchstr, delimiter2);
    	//check that delimiter2 is found
    	if (after_betw == 0) {
    		return 0;
    	}
    	//make betw point to start of substring to be returned
    	betw += strlen(delimiter1);
    	//check that betw is before delimiter2
    	if (betw < after_betw) {
    		int ret_len = after_betw - betw;
    		char* ret = new char[ret_len+1];
    		strncpy(ret, betw, ret_len);
    		return ret;
    	} else {
    		return 0;
    	}
    }
    
    int main() {
    	char* str = strbetween("Stephanie", "tep", "ie");
    	std::cout << str << std::endl;
    	delete[] str;
    	return 0;
    }
    The part that I'm wondering is this: strbetween() uses new[] to allocate memory for the string to be returned.
    Is it safe (i.e. no memory leak) to write main() as:
    Code:
    int main() {
    	std::cout << strbetween("Stephanie", "tep", "ie") << std::endl;
    	return 0;
    }
    considering that there is then no delete[] for the (temporary) string returned by strbetween()?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    Sep 2004
    Posts
    31
    Well I'd always assumed that sort of thing didn't cause a leak, it keeps reference to the memory till the end of that statement doesn't it?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. String Manipulation problems -_-
    By Astra in forum C Programming
    Replies: 5
    Last Post: 12-13-2006, 05:48 PM
  2. C/C++ String Problem.
    By Jaken Veina in forum C++ Programming
    Replies: 7
    Last Post: 07-09-2005, 10:11 PM
  3. Pointer's
    By xlordt in forum C Programming
    Replies: 13
    Last Post: 10-14-2003, 02:15 PM
  4. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM