std::vector erase seg fault
Mar 18, 2015 at 2:11am UTC
I tried a few times to create an example program to show the problem I'm having, but they all worked completely fine. I only seem to get a seg fault when I'm doing specifically this, so apologies for the long code.
It's at line 121, the second time I remove a component. Even when I put a breakpoint there everything seems fine. But it is not. Clearly.
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
#include <iostream>
#include <vector>
class type{
public :
type(){}
virtual ~type(){}
virtual type* clone()=0;
};
class someType:public type{
private :
int data;
public :
someType(){
data =9;
}
~someType(){}
type* clone(){
return new someType(*this );
}
};
class component{
private :
unsigned id_;
type* type_;
public :
component(unsigned id, type &t): id_(id){
type_=t.clone();
}
unsigned getObjectID() const {
return id_;
}
~component(){
delete type_;
}
component(const component &original){
type_=original.type_->clone();
id_=original.id_;
}
};
template <typename T>
class gappy{ //e.g. you ask for component 7, but it gives you component 5 because there was no elements 2 & 3 (hence 'gappy')
private :
std::vector<T> components_; //components sequential with gaps
std::vector<std::pair<unsigned , unsigned > > gaps_; //gaps not sequential
int getIndex(unsigned ID){
unsigned index=ID;
for (unsigned i=0; i<gaps_.size(); i++){
if (ID>=gaps_[i].first){
index-=gaps_[i].second;
}else {
if (ID>=gaps_[i].first-gaps_[i].second){ //ID in gap (not here)
return -1; //for null
}
}
}
if (index>=components_.size()){
return -1; //not in gap, but ID is higher than any in the vector
}
return index;
}
int getGapIndex(int ID){
if (ID>0){
for (std::vector<std::pair<unsigned , unsigned > >::iterator it=gaps_.begin(); it!=gaps_.end(); it++){
if (static_cast <unsigned >(ID)<it->first&&static_cast <unsigned >(ID)>it->first-1-it->second){
return it-gaps_.begin(); //its in this gap
}
}
}
return -1; //not in any gap
}
public :
gappy(){}
~gappy(){}
void addComponent(const T& component){
if (components_.empty()){
if (component.getObjectID()>0){
gaps_.push_back(std::make_pair(component.getObjectID(), component.getObjectID()));
}
}else {
if (component.getObjectID()>components_.back().getObjectID()+1){
gaps_.push_back(std::make_pair(component.getObjectID(), component.getObjectID()-(components_.back().getObjectID()+1)));
}
}
components_.push_back(component);
}
T* getComponent(unsigned ID){
int componentIndex=getIndex(ID);
if (componentIndex==-1){
return nullptr ;
}else {
return &components_[componentIndex];
}
}
void removeComponent(unsigned ID){
if (components_.size()>0){
int i=getIndex(ID);
if (i!=-1){
if (static_cast <unsigned >(i)==components_.size()-1){ //at end
if (!gaps_.empty()&&gaps_.back().first==ID){ //this component had gap before it (now on end)
gaps_.pop_back(); //pop it off
}
}else {
int before = getGapIndex(ID-1);
int after = getGapIndex(ID+1);
if (before==-1&&after==-1){ //no gaps either side
gaps_.push_back(std::make_pair(ID+1, 1)); //add a gap
}else if (before!=-1&&after!=-1){ //gaps both sides
gaps_[after].second+=gaps_[before].second+1;
gaps_.erase(gaps_.begin()+before); //merge gaps (+1 for this space)
}else if (after!=-1){ //gap directly after
gaps_[after].second++;
}else if (before!=-1){ //gap before (gaps_[before].first==ID)
gaps_[before].first=ID+1;
gaps_[before].second++;
}
}
components_.erase(components_.begin()+i);
}
}
}
typename std::vector<T>::iterator begin(){
return components_.begin();
}
typename std::vector<T>::iterator end(){
return components_.end();
}
};
int main(){
someType st;
gappy<component > components_;
for (unsigned i=0; i<=30; i++){
component tComponent(i, st);
components_.addComponent(tComponent);
}
components_.removeComponent(14);
components_.removeComponent(15);
components_.removeComponent(12);
components_.removeComponent(13);
for (unsigned i=0; i<=30; i++){
component* tComponent=components_.getComponent(i);
if (tComponent!=nullptr ){
std::cout<< "component " <<i<<": " << tComponent->getObjectID() << "\n" ;
}
}
return 0;
}
thanks.
Last edited on Mar 18, 2015 at 2:25am UTC
Mar 18, 2015 at 2:44am UTC
you are missing a proper assignment operator for the `component' class
Topic archived. No new replies allowed.