1

I have 2 classes:

class CCandidate {
public:
    float score;
    BitSet documents;
    std::vector<std::vector<int> > phrases;
    int cardinality;

    /** For merging. */
    CCandidate()
    : score(0.0), documents(1), phrases(1), cardinality(0) {}

    /** */
    CCandidate(
    std::vector<int>& phraseIndices, BitSet& documents,
    int cardinality, float score) {

    this->phrases.reserve(1);
    this->phrases.push_back(phraseIndices);

    this->documents = documents;
    this->score = score;
    this->cardinality = cardinality;
    }
};

class PCandidate {
public:
    CCandidate * topics;
    float coverage;

    bool selected;
    bool mostGeneral;
    bool mostSpecific;

    PCandidate(CCandidate * c, float coverage)
    : topics(c), coverage(coverage), 
      selected(true), mostGeneral(true), mostSpecific(true) {}
};

In another class where these classes are used I have something like this:

// ...
std::vector<std::shared_ptr<PCandidate> > phrases(mergeList.size());

for (size_t i = 0; i < mergeList.size(); i++) {
    CCandidate * cc = baseTopics.at(mergeList.get(i));
    std::wcout << cc->toString() << std::endl;
    float coverage = cc->cardinality / result->cardinality;
    std::wcout << "coverage=" << coverage << std::endl;
    phrases.push_back(std::make_shared<PCandidate>(PCandidate(cc, coverage)));

    std::for_each(phrases.begin(), phrases.end(),
        [&](const std::shared_ptr<PCandidate>& pc) { 
            std::wcout << pc->toString() << " "; }); // error
    }
}

anotherMethod(phrases);

// ...

Everything is fine with the CCandidate cc (for now in this verson it is a raw pointer), I can print its contents (method toString() not copied in here) and all is fine. Then I construct the PCandidate Object with the make_shared, push it into the phrases vector and when try to access that `phrases' vector to show me the contents of Pcandidate, the topics cluster I get an segmentation fault.

I could not do something like

std::wcout << ptr->topics->phrases.size() << std::endl

where ptr is a pointer to PCandidate. topics is a pointer to CCandidate containing the phrases vector.

It will give me

==10013== Invalid read of size 8

to see the size of the phrases vector in CCandidate.

I'm a little lost as I do not now where to track down the problem, sitting at this since yesterday. It might be a bloody beginners mistake. Is the lack of missing copy constructors / assignment operators? If yes how should they look like? For example copy the entire phrases vector, like a deep copy? I thought the default copy/assignment should be OK so far.

Would be great if somebody can show me the error or how to fix this! Thanks in advance for your time!

4

1 回答 1

1

phrases最初用mergeList.size() NULL共享指针填充你的向量,然后这些指针之后推入真正的向量。

std::vector<std::shared_ptr<PCandidate> > phrases(mergeList.size());

所以mergeList.size()你的向量中的第一个指针是NULL。失去初始尺寸。

std::vector<std::shared_ptr<PCandidate> > phrases;

如果你想保留容量,你可以,但最终共享指针仍然必须通过它们的引用计数算法。我会跳过它,只做上面的事情。

于 2013-04-24T05:54:30.550 回答