std::vector clear() causes segmentation fault?

B

Bryan

Hello all. I'm fairly new to c++. I've written several programs
using std::vectors, and they've always worked just fine. Until today.

The following is a snippet of my code (sorry, can't include all of it-
it's over 1k lines long). In addition, I'm including an "include"
file where structures like "stack" are defined. Again, it's really
long. I doubt the problem lies there, though, because the include
file is used in many other programs, all of which work fine.

----------------------------------------------------------------------------------
//Removed a lot of bullshit before this code.

//Initialize variables.
stack_ignored=0;//Contains the num. of stack data pts not written
to.
j=0;//Counter that holds the number of data points in current swath.
k=0;//Counter that holds current number of nearby "swaths".
multiple_swaths_indices.push_back(temp_vector_long);//Initialize.
multiple_swaths_indices[k].push_back(0);//Add first index.
j++;
int new_set_of_swaths=0;//Set to 1 when a new set of swaths is
detected.

//Loop through stack data starting at the second data point.
for(i=1;i<stack.numpoints;i++){
//Is this data point in the same swath as the last one?
if((stack.time - stack.time[multiple_swaths_indices[k][j-1]])
<= mcd){
multiple_swaths_indices[k].push_back(i);
j++;
}
if((stack.time - stack.time[multiple_swaths_indices[k][j-1]]) >
mcd or i==stack.numpoints-1){
//If not in the same swath, is the previous swath too small?
if(j<min_swath_pts){
//Ignore the incomplete swath.
stack_ignored += j;
cout << "Ignoring " << j << " data points (incomplete swath).
\n";

//Decrement k because reset procedure will increment it.
k--;

//Remove current swath points.
multiple_swaths_indices.pop_back();

//Reset variables for a new swath.
reset_for_new_swath(i, j, k, multiple_swaths_indices);
cout <<"Successfully reset for new swath!\n";
}
//If not, reset for new swath.
else{
//Reset variables for a new swath.
reset_for_new_swath(i, j, k, multiple_swaths_indices);
cout <<"Successfully reset for new swath!\n";
}

if(k>0){
if((stack.time - stack.time[multiple_swaths_indices[k-1]
[multiple_swaths_indices[k-1].size()-1]]) > msd)
new_set_of_swaths=1;
}
else new_set_of_swaths=1;
if(i==stack.numpoints-1) new_set_of_swaths=1;
if(new_set_of_swaths==1){
if(k>0)
if(i<stack.numpoints-1)
cout << "Pt at i="<<i<<" starts a new set of swaths.
Previous index (from msi) is: "<<multiple_swaths_indices[k-1]
[multiple_swaths_indices[k-1].size()-1]<<endl;
else
if(i<stack.numpoints-1)
cout << "Pt at i="<<i<<" starts a new set of swaths.
Previous index is not available.\n";
if(i==stack.numpoints-1)
cout << "Pt at i="<<i<<" is the end of the stack file.\n";

if(j<min_swath_pts){
//Ignore the incomplete swath.
stack_ignored += j;
cout <<"Problem: Ignoring "<<j<<" data points (incomplete
swath).\n";

//Decrement k because that swath is being ignored.
k--;

//Remove current swath points.
multiple_swaths_indices.pop_back();

//Set j to the size of msi[k].
j = multiple_swaths_indices[k].size();
}

//Keep collecting swaths until too great a gap exists.
//Only fit and remove once/rev if there are "enough" swaths.
if(k >= N-1){
//Reset variables for a new SET of swaths.
new_set_of_swaths=0;
cout <<"About to reset for a new set of swaths.\n";
multiple_swaths_indices.clear();
cout<<"Successfully reset for a new set of swaths.\n";
}//End of "if enough swaths exist" commands
}//End of "if next data point isn't even in a nearby swath".
}//End of "if not contiguous or the last datapoint" if statement.
}//End of loop through stack data.

}//End of main() code- I've cut out LOTS of extraneous bullshit.

int reset_for_new_swath(long &i, long &j,long &k,
vector< vector<long> >
&multiple_swaths_indices){
vector<long> temp_vector_long;
j=0;
k++;
multiple_swaths_indices.push_back(temp_vector_long);
multiple_swaths_indices[k].push_back(i);
j++;
return 0;
}

int reset_for_new_set_of_swaths(long &i, long &j,long &k,
vector< vector<long> >
&multiple_swaths_indices){
vector<long> temp_vector_long;
j=0;
k=0;
multiple_swaths_indices.clear();
multiple_swaths_indices.push_back(temp_vector_long);
multiple_swaths_indices[k].push_back(i);
j++;
return 0;
}

----------------------------------------------------------------------------------

When executed, this code (or, rather, the complete program from which
this code has been snipped) produces the following output:

----------------------------------------------------------------------------------
Ignoring 32 data points (incomplete swath).
Successfully reset for new swath!
Pt at i=744 starts a new set of swaths. Previous index (from msi) is:
711
Before reset for new swath: k: 6 j: 1 msi.size(): 7
Problem: Ignoring 1 data points (incomplete swath).
Ignoring 6 swaths (Need 11 swaths).
Ignoring 58 data points (incomplete swath).
Successfully reset for new swath!
Ignoring 31 data points (incomplete swath).
Successfully reset for new swath!
Pt at i=1929 starts a new set of swaths. Previous index (from msi)
is: 1928
Before reset for new swath: k: 9 j: 1 msi.size(): 10
Problem: Ignoring 1 data points (incomplete swath).
Ignoring 9 swaths (Need 11 swaths).
Pt at i=5716 starts a new set of swaths. Previous index (from msi)
is: 5715
Before reset for new swath: k: 25 j: 1 msi.size(): 26
Problem: Ignoring 1 data points (incomplete swath).
About to reset for a new set of swaths.
Segmentation fault (core dumped)
----------------------------------------------------------------------------------

Notice how the segmentation fault occurs right after "About to reset
for a new set of swaths." and the message "Successfully reset for a
new set of swaths." never appears. I believe this means that the
statement "multiple_swaths_indices.clear();" must be causing the
segmentation fault.

Does anyone know why this is happening? I've been staring at this
code for nearly a week now, and I don't have ANY idea why it's
crashing. I've been inserting cout statements like crazy, trying to
identify anything strange, but everything looks normal as far as I can
tell...

Help!

(Please...)

-Bryan
 
B

bjeremy

Hello all. I'm fairly new to c++. I've written several programs
using std::vectors, and they've always worked just fine. Until today.

The following is a snippet of my code (sorry, can't include all of it-
it's over 1k lines long). In addition, I'm including an "include"
file where structures like "stack" are defined. Again, it's really
long. I doubt the problem lies there, though, because the include
file is used in many other programs, all of which work fine.

----------------------------------------------------------------------------------
//Removed a lot of bullshit before this code.

//Initialize variables.
stack_ignored=0;//Contains the num. of stack data pts not written
to.
j=0;//Counter that holds the number of data points in current swath.
k=0;//Counter that holds current number of nearby "swaths".
multiple_swaths_indices.push_back(temp_vector_long);//Initialize.
multiple_swaths_indices[k].push_back(0);//Add first index.
j++;
int new_set_of_swaths=0;//Set to 1 when a new set of swaths is
detected.

//Loop through stack data starting at the second data point.
for(i=1;i<stack.numpoints;i++){
//Is this data point in the same swath as the last one?
if((stack.time - stack.time[multiple_swaths_indices[k][j-1]])
<= mcd){
multiple_swaths_indices[k].push_back(i);
j++;
}
if((stack.time - stack.time[multiple_swaths_indices[k][j-1]]) >
mcd or i==stack.numpoints-1){
//If not in the same swath, is the previous swath too small?
if(j<min_swath_pts){
//Ignore the incomplete swath.
stack_ignored += j;
cout << "Ignoring " << j << " data points (incomplete swath).
\n";

//Decrement k because reset procedure will increment it.
k--;

//Remove current swath points.
multiple_swaths_indices.pop_back();

//Reset variables for a new swath.
reset_for_new_swath(i, j, k, multiple_swaths_indices);
cout <<"Successfully reset for new swath!\n";
}
//If not, reset for new swath.
else{
//Reset variables for a new swath.
reset_for_new_swath(i, j, k, multiple_swaths_indices);
cout <<"Successfully reset for new swath!\n";
}

if(k>0){
if((stack.time - stack.time[multiple_swaths_indices[k-1]
[multiple_swaths_indices[k-1].size()-1]]) > msd)
new_set_of_swaths=1;
}
else new_set_of_swaths=1;
if(i==stack.numpoints-1) new_set_of_swaths=1;
if(new_set_of_swaths==1){
if(k>0)
if(i<stack.numpoints-1)
cout << "Pt at i="<<i<<" starts a new set of swaths.
Previous index (from msi) is: "<<multiple_swaths_indices[k-1]
[multiple_swaths_indices[k-1].size()-1]<<endl;
else
if(i<stack.numpoints-1)
cout << "Pt at i="<<i<<" starts a new set of swaths.
Previous index is not available.\n";
if(i==stack.numpoints-1)
cout << "Pt at i="<<i<<" is the end of the stack file.\n";

if(j<min_swath_pts){
//Ignore the incomplete swath.
stack_ignored += j;
cout <<"Problem: Ignoring "<<j<<" data points (incomplete
swath).\n";

//Decrement k because that swath is being ignored.
k--;

//Remove current swath points.
multiple_swaths_indices.pop_back();

//Set j to the size of msi[k].
j = multiple_swaths_indices[k].size();
}

//Keep collecting swaths until too great a gap exists.
//Only fit and remove once/rev if there are "enough" swaths.
if(k >= N-1){
//Reset variables for a new SET of swaths.
new_set_of_swaths=0;
cout <<"About to reset for a new set of swaths.\n";
multiple_swaths_indices.clear();
cout<<"Successfully reset for a new set of swaths.\n";
}//End of "if enough swaths exist" commands
}//End of "if next data point isn't even in a nearby swath".
}//End of "if not contiguous or the last datapoint" if statement.
}//End of loop through stack data.

}//End of main() code- I've cut out LOTS of extraneous bullshit.

int reset_for_new_swath(long &i, long &j,long &k,
vector< vector<long> >
&multiple_swaths_indices){
vector<long> temp_vector_long;
j=0;
k++;
multiple_swaths_indices.push_back(temp_vector_long);
multiple_swaths_indices[k].push_back(i);
j++;
return 0;

}

int reset_for_new_set_of_swaths(long &i, long &j,long &k,
vector< vector<long> >
&multiple_swaths_indices){
vector<long> temp_vector_long;
j=0;
k=0;
multiple_swaths_indices.clear();
multiple_swaths_indices.push_back(temp_vector_long);
multiple_swaths_indices[k].push_back(i);
j++;
return 0;

}

----------------------------------------------------------------------------------

When executed, this code (or, rather, the complete program from which
this code has been snipped) produces the following output:

----------------------------------------------------------------------------------
Ignoring 32 data points (incomplete swath).
Successfully reset for new swath!
Pt at i=744 starts a new set of swaths. Previous index (from msi) is:
711
Before reset for new swath: k: 6 j: 1 msi.size(): 7
Problem: Ignoring 1 data points (incomplete swath).
Ignoring 6 swaths (Need 11 swaths).
Ignoring 58 data points (incomplete swath).
Successfully reset for new swath!
Ignoring 31 data points (incomplete swath).
Successfully reset for new swath!
Pt at i=1929 starts a new set of swaths. Previous index (from msi)
is: 1928
Before reset for new swath: k: 9 j: 1 msi.size(): 10
Problem: Ignoring 1 data points (incomplete swath).
Ignoring 9 swaths (Need 11 swaths).
Pt at i=5716 starts a new set of swaths. Previous index (from msi)
is: 5715
Before reset for new swath: k: 25 j: 1 msi.size(): 26
Problem: Ignoring 1 data points (incomplete swath).
About to reset for a new set of swaths.
Segmentation fault (core dumped)
----------------------------------------------------------------------------------

Notice how the segmentation fault occurs right after "About to reset
for a new set of swaths." and the message "Successfully reset for a
new set of swaths." never appears. I believe this means that the
statement "multiple_swaths_indices.clear();" must be causing the
segmentation fault.

Does anyone know why this is happening? I've been staring at this
code for nearly a week now, and I don't have ANY idea why it's
crashing. I've been inserting cout statements like crazy, trying to
identify anything strange, but everything looks normal as far as I can
tell...

Help!

(Please...)

-Bryan



Honestly, for me, just looking at your code it is hard to say. I don't
readily see the problem. However, if you happned to have a debugger on
hand, you could probably pin point the exact problem... If you are on
a Linux/Unix distribution, gdb should be readily available for you to
use. If you are on windows the MSVC++ debugger should be able to find
your problem.
 
J

Juha Nieminen

Bryan said:
(of course, any other gurus out there who can decipher my mess and
figure out why a .clear() statement is causing a segmentation fault
are still more than welcome to enlighten me...)

In my experience if an operation which normally can not be used
wrongly (such as the clear() function of a std::vector) is causing a
segmentation fault it's because you are writing something outside of
boundaries (typically outside of an array) somewhere else, and the crash
with that unrelated operation is just a delayed symptom. It's often the
case that the bug is in no way related to the data data structure or the
function which is crashing.

These can be quite hard to find, but programs like valgrind can be of
great help in that.

(Of course another possible situation where a clear() call can cause a
segmentation fault is if what you have is a pointer or reference to the
vector and it happens to be a null pointer or a reference pointing to
null (or some other invalid memory location), in which case you are
calling it for an invalid memory address, but I assume you have checked
this is not the case.)
 
B

Bryan

Honestly, for me, just looking at your code it is hard to say. I don't
readily see the problem. However, if you happned to have a debugger on
hand, you could probably pin point the exact problem... If you are on
a Linux/Unix distribution, gdb should be readily available for you to
use. If you are on windows the MSVC++ debugger should be able to find
your problem.

Yeah, I realize I dumped a large amount of cryptic code in that
message. The fact that I had to strip out a lot of the commands in
the program in order to not post a 1000+ line message probably doesn't
help.

I'd never heard of gdb before, but I'm trying to use it for the first
time right now to see if I can figure out what's going on.

Thanks!

(of course, any other gurus out there who can decipher my mess and
figure out why a .clear() statement is causing a segmentation fault
are still more than welcome to enlighten me...)

-Bryan
 
G

Guest

Hello all. I'm fairly new to c++. I've written several programs
using std::vectors, and they've always worked just fine. Until today.

The following is a snippet of my code (sorry, can't include all of it-
it's over 1k lines long). In addition, I'm including an "include"
file where structures like "stack" are defined. Again, it's really
long. I doubt the problem lies there, though, because the include
file is used in many other programs, all of which work fine.

[snip code]
Notice how the segmentation fault occurs right after "About to reset
for a new set of swaths." and the message "Successfully reset for a
new set of swaths." never appears. I believe this means that the
statement "multiple_swaths_indices.clear();" must be causing the
segmentation fault.

Does anyone know why this is happening? I've been staring at this
code for nearly a week now, and I don't have ANY idea why it's
crashing. I've been inserting cout statements like crazy, trying to
identify anything strange, but everything looks normal as far as I can
tell...

If the segfault occurs when calling std::vector<T>::clear() it means
that either your implementation of the standard library is buggy or that
you have a problem in one of your destructors. Since the probability of
a problem with the implementation is near zero I thing you have a
problem with the destructor of the class that were stored in the vector.
Probably the class contains a pointer which is dereferenced in some way
during destruction, and that pointer is no longer valid.

As bjeremy said, by running it through a debugger you should be able to
find the exact place of the problem.
 
B

BobR

Bryan wrote in message...
file://Removed a lot of bullshit before this code.

Reduce your code to the *smallest* compilable program that demonstrates your
problem. (not clear how you declared 'multiple_swaths_indices' and
'temp_vector_long'.).

Assuming 'multiple_swaths_indices' is a std::vector, you clear() it, then
try to access elements that no longer exist. (a try-catch will show an
std::eek:ut_of_range exception, if you use the '.at()' accessor (not []).)

Change this line:
cout<<"Successfully reset for a new set of swaths.\n";
..... to:
cout<<"Successfully reset for a new set of swaths.\n"<<std::endl;
..... if you want to 'see' it.
[The buffer is not flushed before you return to the top of your loop where
the illegal element access happens.]


FAQ http://www.parashift.com/c++-faq-lite
See the sections on how to post (section 5).
[if this site is back up.]
 
B

Bryan

As suggested, I've tried to include some more code from the original
program (such as the definition of multiple_swaths_indices!). Here it
is:

//grace.hpp defines data type "stack_struct", among other things.
#include "grace.hpp"

int main(){
stack_struct stack;
float onelat,onelon,oneaccel;
long onetime,i,j,k,g,f,l;
int N=11;//Controls number of swaths over which to fit once/rev.
int N2=floor(N/2);//Used to move the fitting window.
int mcd;//Max. contiguous delay. Any delay b/w pts>mcd=newswath
int msd;//Max. swath delay. Any delay>msd=stop counting swaths.
int min_swath_pts;//Any fewer points and this isn't a swath.
vector< vector<long> > multiple_current_indices(N);
vector< vector<long> > multiple_swaths_indices;
long stack_ignored;//Contains the num. of stack data pts not written
to.
vector<long> temp_vector_long;//Used to push_back vectors of long
vectors.
vector<double> temp_vector_double;//"" "" "" "" dbl vectors.

//I've snipped out a lot of code here that read a file
//containing data that gets saved in the structure "stack".

mcd = 3600;//Max. contiguous delay. Any delay b/w
pts>mcd=newswath
msd = 12*mcd;//Max. swath delay. Any delay>msd=stop counting
swaths.
min_swath_pts = 60;//Any fewer points and this isn't a swath.

//Initialize variables.
stack_ignored=0;//Contains the num. of stack data pts not
written to.
j=0;//Counter that holds the number of data points in current
swath.
k=0;//Counter that holds current number of nearby "swaths".
multiple_swaths_indices.push_back(temp_vector_long);//
Initialize.
multiple_swaths_indices[k].push_back(0);//Add first index.
j++;
int new_set_of_swaths=0;//Set to 1 when a new set of swaths is
detected.

//Loop through stack data starting at the second data point.
for(i=1;i<stack.numpoints;i++){
//Is this data point in the same swath as the last one?
if((stack.time - stack.time[multiple_swaths_indices[k]
[j-1]]) <= mcd){
multiple_swaths_indices[k].push_back(i);
j++;
}
if((stack.time - stack.time[multiple_swaths_indices[k]
[j-1]]) > mcd or i==stack.numpoints-1){
//If not in the same swath, is the previous swath too small?
if(j<min_swath_pts){
//Ignore the incomplete swath.
stack_ignored += j;
cout << "Ignoring " << j << " data points (incomplete
swath).\n";

//Decrement k because reset procedure will increment it.
k--;

//Remove current swath points.
multiple_swaths_indices.pop_back();

//Reset variables for a new swath.
//cout <<"About to reset for new swath!\n";
reset_for_new_swath(i, j, k, multiple_swaths_indices);
cout <<"Successfully reset for new swath!\n";
}
//If not, reset for new swath.
else{
//Reset variables for a new swath.
reset_for_new_swath(i, j, k, multiple_swaths_indices);
}

if(k>0){
if((stack.time - stack.time[multiple_swaths_indices[k-1]
[multiple_swaths_indices[k-1].size()-1]]) > msd)
new_set_of_swaths=1;
}
else new_set_of_swaths=1;
if(i==stack.numpoints-1) new_set_of_swaths=1;
if(new_set_of_swaths==1){
if(k>0)
if(i<stack.numpoints-1)
cout << "Pt at i="<<i<<" starts a new set of swaths.
Previous index (from msi) is: "<<multiple_swaths_indices[k-1]
[multiple_swaths_indices[k-1].size()-1]<<endl;
else
if(i<stack.numpoints-1)
cout << "Pt at i="<<i<<" starts a new set of swaths.
Previous index is not available.\n";
if(i==stack.numpoints-1)
cout << "Pt at i="<<i<<" is the end of the stack file.
\n";

if(j<min_swath_pts){
cout<<"Before reset for new swath: k: "<<k<<" j: "<<j<<"
msi.size(): "<<multiple_swaths_indices.size()<<endl;

//Ignore the incomplete swath.
stack_ignored += j;
cout <<"Problem: Ignoring "<<j<<" data points
(incomplete swath).\n";

//Decrement k because that swath is being ignored.
k--;

//Remove current swath points.
multiple_swaths_indices.pop_back();

//Set j to the size of msi[k].
j = multiple_swaths_indices[k].size();
}

//Keep collecting swaths until too great a gap exists.
//Only fit and remove once/rev if there are "enough"
swaths.
if(k >= N-1){
//Snipped out lots of code here that fits cosine
//functions to the data being collected from the
//stack structure.

//Reset variables for a new SET of swaths.
new_set_of_swaths=0;
cout <<"About to reset for a new set of swaths.\n";
multiple_swaths_indices.clear();
//reset_for_new_set_of_swaths(i, j, k,
multiple_swaths_indices);
cout<<"Successfully reset for a new set of swaths!\n";
cout<<"After reset for new swath: k: "<<k<<" j: "<<j<<"
msi.size(): "<<multiple_swaths_indices.size()<<endl;
}//End of "if enough swaths exist" commands
else{
//Ignore these last few swaths.
cout << "Ignoring " << k+1 << " swaths (Need "<<N<< "
swaths).\n";
for(g=0;g<multiple_swaths_indices.size();g++)
stack_ignored += multiple_swaths_indices[g].size();

//Reset variables for a new SET of swaths.
new_set_of_swaths=0;
reset_for_new_set_of_swaths(i, j, k,
multiple_swaths_indices);
}//End of "if not enough swaths" else statement.
}//End of "if next data point isn't even in a nearby
swath".
}//End of "if not contiguous or the last datapoint" if
statement.
}//End of loop through stack data.
return 0;
}

int reset_for_new_swath(long &i, long &j,long &k,
vector< vector<long> >
&multiple_swaths_indices){

vector<long> temp_vector_long;
j=0;
k++;
multiple_swaths_indices.push_back(temp_vector_long);
multiple_swaths_indices[k].push_back(i);
j++;
return 0;
}

int reset_for_new_set_of_swaths(long &i, long &j,long &k,
vector< vector<long> >
&multiple_swaths_indices){

vector<long> temp_vector_long;
j=0;
k=0;
multiple_swaths_indices.clear();
multiple_swaths_indices.push_back(temp_vector_long);
multiple_swaths_indices[k].push_back(i);
j++;
return 0;
}
 
J

Juha Nieminen

Erik said:
I thing you have a
problem with the destructor of the class that were stored in the vector.

That's not necessarily the cause. Writing outside of allocated arrays
can produce erratic behavior like this.
 
B

Bryan

I found the error. One of the lines in the program says "j =
multiple_swaths_indices[k].size();"

I discovered that k= -1 for one loop, which meant that j=some random
number like 40 billion.

Once I fixed this, the segmentation fault went away. I still think
it's weird that the segmentation fault occurred WAY later in the
program, but c'est la vie.

Thank you all for your help!

-Bryan
 
J

Juha Nieminen

Bryan said:
Once I fixed this, the segmentation fault went away. I still think
it's weird that the segmentation fault occurred WAY later in the
program, but c'est la vie.

That's just how C/C++ behaves sometimes. Valgrind would have probably
caught that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top