简体   繁体   English

在C ++中迭代地图时,SIGSEGV信号

[英]SIGSEGV signal while iterating a map in C++

I am trying to fix this for about 5 days and no luck, every solution I tried failed. 我试图修复此问题大约5天,没有运气,我尝试的每个解决方案都失败了。

I found some cause of the SIGSEGV below but nothing helped What is SIGSEGV run time error in C++? 我在下面找到了SIGSEGV的某些原因,但没有任何帮助。C ++中的SIGSEGV运行时错误是什么?

Ok, here is the code. 好的,这是代码。 I have 2 instances, which contain some keywords-features and their scores 我有2个实例,其中包含一些关键字功能及其得分

I want to get their eucleidian distance, which means I have to save all the keywords for each of the instances, then find the diffs for the keywords of the first one with those of the second and then find the diffs for the remaining of the second instance. 我想获得他们的距离,这意味着我必须保存每个实例的所有关键字,然后找到第一个关键字与第二个关键字的差异,然后找到第二个关键字的差异实例。 What I want is while iterating the first map, to be able to delete elements from the second. 我想要的是在迭代第一个地图时,能够从第二个地图中删除元素。 The following method is called multiple times as we have two message collections, and every message from the first one is compared with every message from the second. 由于我们有两个消息集合,因此多次调用以下方法,并将第一个消息中的每个消息与第二个消息中的每个消息进行比较。

I have this code but it suddenly stops although I checked it is working for some seconds with multiple cout I put in some places 我有这段代码,但是尽管我检查了它是否在某些地方放了几下,但突然停了下来

Note that this is for a university task so I cannot use boost and all those tricks. 请注意,这是一项大学任务,因此我无法使用boost和所有这些技巧。 But I would like to know the way to bypass the problem I am into. 但是我想知道绕过我所遇到的问题的方法。

float KNNClassifier::distance(const Instance& inst1, const Instance& inst2) {   
map<string,unsigned> feat1;
map<string,unsigned> feat2;
for (unsigned i=0; i<inst1.getNumberOfFeatures(); i++) {
  feat1[inst1.getFeature(i)]=i;
}
for (unsigned i=0; i<inst2.getNumberOfFeatures(); i++) {
  feat2[inst2.getFeature(i)]=i;
}
float dist=0;

map<string,unsigned>::iterator it;
for (it=feat1.begin(); it!=feat1.end(); it++) {
  if (feat2.find(it->first)!=feat2.end()) {//if and only if it exists in inst2
    dist+=pow( (double) inst1.getScore(it->second) - inst2.getScore(feat2[it->first]) , 2.0);
    feat2.erase(it->first);
  }
  else {
    dist+=pow( (double) inst1.getScore(it->second) , 2.0);
  }
}

for (it=feat2.begin(); it!=feat2.end(); it++) {//for the remaining words
  dist+=pow( (double) inst2.getScore(it->second) , 2.0);
}
feat1.clear(); feat2.clear(); //ka8arizoume ta map gia thn epomenh xrhsh
return sqrt(dist);    
}

and I also tried this idea in order to not have to delete something but it suddenly stops too. 为了避免不必删除某些内容,我也尝试了这个想法,但是它突然也停止了。

float KNNClassifier::distance(const Instance& inst1, const Instance& inst2) {
map<string,unsigned> feat1;
map<string,unsigned> feat2;
map<string,bool> exists;
for (unsigned i=0; i<inst1.getNumberOfFeatures(); i++) {
  feat1[inst1.getFeature(i)]=i;
}
for (unsigned i=0; i<inst2.getNumberOfFeatures(); i++) {
  feat2[inst2.getFeature(i)]=i;
  exists[inst2.getFeature(i)]=false;
  if (feat1.find(inst2.getFeature(i))!=feat1.end()) {
    exists[inst2.getFeature(i)]=true;
  }
}
float dist=0;
map<string,unsigned>::iterator it;
for (it=feat1.begin(); it!=feat1.end(); it++) {
  if (feat2.find(it->first)!=feat2.end()) {
    dist+=pow( (double) inst1.getScore(it->second) - inst2.getScore(feat2[it->first]) ,      2.0);
  }
  else {
    dist+=pow( (double) inst1.getScore(it->second) , 2.0);
  }
}

for (it=feat2.begin(); it!=feat2.end(); it++) {
  if(it->second==false){//if it is true, it means the diff was done in the previous iteration
    dist+=pow( (double) inst2.getScore(it->second) , 2.0);
  }
}

feat1.clear(); feat2.clear(); exists.clear();
return sqrt(dist);
}

The code per se seems to be OK (the error I thought I spotted earlier wasn't one). 代码本身似乎还可以(我以为我之前发现的错误不是一个)。 However, there may be an easier approach: 但是,可能有一种更简单的方法:

  1. Instead of looking up the string from the first set in the second set, it would be possible to move through the two lists simultanously and advance the iterator to the smaller element or both iterators if they use the same string. 除了可以从第二组中的第一组中查找字符串之外,还可以同时遍历两个列表,并将迭代器前进到较小的元素,或者如果它们使用相同的字符串,则将两个迭代器都前进。 The corresponding computation is done directly in each case. 每种情况下都直接进行相应的计算。
  2. I would personally use two sorted std::vector<std::pair<std::string, unsigned int> > for this but std::map<std::string, unsigned int> works as well. 我个人将使用两种排序的std::vector<std::pair<std::string, unsigned int> > ,但std::map<std::string, unsigned int>也可以。

I don't have access to your Instance class and, thus, haven't tested it but something like the below should work. 我无权访问您的Instance类,因此尚未对其进行测试,但类似以下的内容应该可以工作。

struct compare1st {
    bool operator()(std::pair<std::string, unsigned int> const& p1,
                    std::pair<std::string, unsigned int> const& p2) const {
        return p1.first < p2.first;
    }
};

std::vector<std::pair<std::string, unsigned int> > fill(Instance const& inst) {
    std::vector<std::pair<std::string, unsigned int> > rc;
    for (unsigned int i(0), end(inst.getNumberOfFeatures()); i != end; ++i) {
        rc.push_back(std::make_pair(inst.getFeature(i), i));
    }
    std::sort(rc.begin(), rc.end(), compare1st());
    return rc;
}
double square(double d) { // pow(d, 2.0) is fairly expensive
    return d * d;
}

float KNNClassifier::distance(const Instance& inst1, const Instance& inst2) {   
    typedef std::pair<std::string, unsigned int> Pair;
    std::vector<Pair> feat1 = fill(inst1);
    std::vector<Pair> feat2 = fill(inst2);

    std::vector<Pair>::const_iterator it1(feat1.begin()), end1(feat1.end());
    std::vector<Pair>::const_iterator it2(feat2.begin()), end2(feat2.end());
    double result(0.0);
    while (it1 != end1 && it2 != end2) {
        if (it1 != end1 && (it2 == end2 || it1->first < it2->first)) {
            result += square(inst1.getScore((it1++)->second);
        }
        else if (it2 != end2 && (it1 == end1 || it2->first < it1->first))
            result += square(inst2.getScore((it2++)->second);
        }
        else {
            result += square(inst1.getScore((it1++)->second)
                             -  inst2.getScore((it2++)->second);
        }
    }
    return sqrt(result);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM