Reputation: 737
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!
Upvotes: 1
Views: 144
Reputation: 66244
You're populating your phrases
vector initially with mergeList.size()
NULL shared-pointers, then pushing the real ones in after those.
std::vector<std::shared_ptr<PCandidate> > phrases(mergeList.size());
So the first mergeList.size()
pointers in your vector are NULL. Lose the initial sizing.
std::vector<std::shared_ptr<PCandidate> > phrases;
If you want to reserve capacity, you can, but ultimately the shared pointers are still going to have to go through their reference counting algorithm either way. I'd skip it and just do the above.
Upvotes: 1