Segfault with substr

So I have narrowed down a segfault to a trim function that's using substr, where the substr call is ultimately causing my segfault. I've been doing a fair amount of searching both on these forums and google and I understand that it's somehow related to how substr read or writes to memory where it's not allowed to, but none of the discussions have been fairly close to what I'm trying to do.

The function looks like this

1
2
3
4
5
6
string trim ( string s, unsigned int l )
{
   if(s.length() >= l)
      return s.substr(0,l) + "...";
   return s;
}


and the code that is calling the function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...

vector<Movie*> tmp;
for(i = 0; i < movies.size(); i++)
{
   tmp.push_back( new Movie(movies[i]->title, movies[i]->type) );
}
		
alternateSort(tmp);

for(i = 0; i < tmp.size(); i++)
{
   cout << tmp[i]->title << ' ' << tmp[i]->title.length() << endl;
   trim(tmp[i]->title, 30);
}

...


Another interesting thing is that this only happens if tmp contains more than one element and the segfault always happens on the exact same element each time. But if the vector only contains one element it instead throws this error

1
2
3
3(30249) malloc: *** error for object 0x7fff5fbff850: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap


Like I said I've understood I'm doing some nasty things to the memory, but can't see what exactly. Oh, and if you need any other code or info that I haven't already provided, just let me know!
I do not see any problem with your code that you showed. Only it is not known how function alternateSort works and whether you defined correctly the copy constructor and the copy assignment operator for class Movie.
yvan wrote:
So I have narrowed down a segfault to a trim function that's using substr, where the substr call is ultimately causing my segfault. I've been doing a fair amount of searching both on these forums and google and I understand that it's somehow related to how substr read or writes to memory where it's not allowed to, but none of the discussions have been fairly close to what I'm trying to do.

The function looks like this

1
2
3
4
5
6
string trim ( string s, unsigned int l )
{
   if(s.length() >= l)
      return s.substr(0,l) + "...";
   return s;
}


and the code that is calling the function

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
...

vector<Movie*> tmp;
for(i = 0; i < movies.size(); i++)
{
   tmp.push_back( new Movie(movies[i]->title, movies[i]->type) );
}
		
alternateSort(tmp);

for(i = 0; i < tmp.size(); i++)
{
   cout << tmp[i]->title << ' ' << tmp[i]->title.length() << endl;
   trim(tmp[i]->title, 30);
}

...


Another interesting thing is that this only happens if tmp contains more than one element and the segfault always happens on the exact same element each time. But if the vector only contains one element it instead throws this error

3(30249) malloc: *** error for object 0x7fff5fbff850: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap


Like I said I've understood I'm doing some nasty things to the memory, but can't see what exactly. Oh, and if you need any other code or info that I haven't already provided, just let me know!


My guess is that substr() assumes there are enough characters to cover for the value of 'l'. See if this gets rid of the problem:

return s.substr(0, std::min(l, s.length())) + "...";

The use of std::min() requires you to #include <algorithm>.
@webJose
1
2
3
4
5
My guess is that substr() assumes there are enough characters to cover for the value of 'l'. See if this gets rid of the problem:
 
return s.substr(0, std::min(l, s.length())) + "...";
 
The use of std::min() requires you to #include <algorithm>.  


It is a wrong guess because there is the following check in the function

1
2
   if(s.length() >= l)
      return s.substr(0,l) + "..."; 





@vlad from moscow
now that you mention it, I havent defined either one of those. how would i go about correctly doing that?

just in case, the alernationSort looks like this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void alternateSort ( vector<Movie*>& v )
{
   Movie* tmp;
   unsigned int i;
   unsigned int j;
	
   if(v[0]->type != Movie::DVD)
   {
      for(i = 1; i < v.size(); i++)
      {
         if(v[i]->type != v[0]->type)
         {
            tmp = v[0];
            v[0] = v[i];
            v[i] = tmp;
            break;
         }
      }
   }
	
   for(i = 1; i < v.size(); i++)
   {
      if(v[i]->type == v[i - 1]->type)
      {
         for(j = i + 1; j < v.size(); j++)
         {
            if(v[j]->type != v[i]->type)
            {
               tmp = v[i];
               v[i] = v[j];
               v[j] = tmp;
               break;
            }
         }
      }
   }
	
   delete tmp;
}
I see that the function has a serious problem. It deletes tmp that has the same value as some element of the vector. I do not think that you should delete tmp.
Last edited on
thanks vlad! that resolved the problem! i guess i'm still in habit from other languages ;)
Topic archived. No new replies allowed.