7
votes

this is my first post here. As i am newbie, the problem might be stupid. I was writing a piece of code while the following error message shown,

terminate called after throwing an instance of 'std::length_error'

what(): basic_string::_S_create

/home/gcj/finals /home/gcj/quals where Aborted

the following is the offending code especially Line 39 to Line 52. It is weired for me as this block of code is almost same as the Line64 to Line79.



int main(){


std::vector<std::string> dirs, need;
std::string tmp_str;
std::ifstream fp_in("small.in");
std::ofstream fp_out("output");
std::string::iterator iter_substr_begin, iter_substr_end;
std::string slash("/");

int T, N, M;

fp_in>>T;
for (int t = 0; t < T; t++){
  std::cout<<" time "<< t << std::endl;

  fp_in >> N >> M;
  for (int n =0; n<N; n++){
    fp_in>>tmp_str;
    dirs.push_back(tmp_str);
    tmp_str.clear();
  }
  for (int m=0; m<M; m++){
    fp_in>>tmp_str;
    need.push_back(tmp_str);
    tmp_str.clear();
  }


  for (std::vector<std::string>::iterator iter = dirs.begin(); iter!=dirs.end(); iter++){
    for (std::string::iterator iter_str = (*iter).begin()+1; iter_str<(*iter).end(); ++iter_str){
  if ((*iter_str)=='/') {
    std::string tmp_str2((*iter).begin(), iter_str);
    if (find(dirs.begin(), dirs.end(), tmp_str2)==dirs.end()) {
      dirs.push_back(tmp_str2);
    }

  }

    }

  }

  for (std::vector<std::string>::iterator iter_tmp = dirs.begin(); iter_tmp!= dirs.end(); ++iter_tmp)
    std::cout<<*iter_tmp<<" ";


  dirs.clear();
  std::cout<<std::endl;
  std::cout<<" need "<<std::endl;

  //processing the next


  for (std::vector<std::string>::iterator iter_tmp = need.begin(); iter_tmp!=need.end(); ++iter_tmp)
    std::cout<<*iter_tmp<<" ";

  std::cout<<"  where ";

  for (std::vector<std::string>::iterator iter = need.begin(); iter!=need.end(); iter++){
    for (std::string::iterator iter_str = (*iter).begin()+1; iter_str<(*iter).end(); ++iter_str){
  if ((*iter_str)=='/') {
    std::string tmp_str2((*iter).begin(), iter_str);
    if (find(need.begin(), need.end(), tmp_str2)==need.end()) {
      need.push_back(tmp_str2);
    }


  }

    }

  }

  for (std::vector<std::string>::iterator iter_tmp = need.begin(); iter_tmp!= need.end(); ++iter_tmp)
    std::cout<<*iter_tmp<<" ";


  need.clear();
  std::cout<<std::endl;


  //finish processing the next 
 }


for (std::vector<std::string>::iterator iter= dirs.begin(); iter!=dirs.end(); iter++)
  std::cout<<*iter<<" ";
std::cout<<std::endl;



for (std::vector<std::string>::iterator iter= need.begin(); iter!=need.end(); iter++)
  std::cout<<*iter<<" ";
std::cout<<std::endl;


fp_out.close();


}

best regards, Mark

2
Please mark line 39 to 52. There's no line numbers in SO. - kennytm
It looks like you're doing a lot of work to enforce that dirs and need are unique. Maybe switch from vector to set, and it'll do it automatically. - Stephen
People are not going to help unless you make it easy. 1) The code is not complete and does not compile. 2) How can we test it the same way as you without the same input file? 3) Line numbers for you are unlikely to match line numbers for anybody else (mark the bad code with a comment). - Martin York
I doubt it's your problem, but you should use != instead of < to compare iterators. < will fail for nonsequential in memory containers (e.g. set,map). - Stephen

2 Answers

4
votes

You are adding items to the dirs and need vectors while iterating over them. This is not allowed: if adding an item requires a reallocation, it will invalidate all existing iterators, and can cause various errors when you next access them.

0
votes

I don't know what is proper way to do it, but since it was hard to find this answer, I'll put it here. "terminate called after throwing 'foo'" just means that the exception was not catched by any try ... catch clause.