Long time reader, first one I didn't find an answer to...
I'm writing a c++(11) class in a mainly C project which is swig-wrapped to Python. I can not expose c++ types to Python, only c-types. I need to save some c++ stl containers during c++ -> python -> c++ which is possible with opaque structs.
However when filling the struct* imp
I encounter a segfault for std::list and std::vector, whereas std::unordered_map is fine. MWE:
#include <stdio.h>
//Include c++ stuff here
#include <iostream>
#include <unordered_map>
#include <list>
#include <queue>
#include <utility>
#include <algorithm>
//https://stackoverflow.com/a/27216842/9152353
template <typename T>
struct hash_vector {
T operator()(const std::vector<T> &V) const {
T hash = V.size();
for(auto &i : V) {
hash ^= i + 0x9e3779b9 + (hash << 6) + (hash >> 2);
}
return hash;
}
};
typedef std::vector<size_t> vec;
typedef std::unordered_map<const vec, vec, hash_vector<size_t>> _map;
typedef std::list<std::pair<std::list<vec>, std::list<size_t>>> complexList_t;
typedef std::list<size_t> listSize_t;
struct IntermediateResults {
_map theMap;
complexList_t cmplxList;
listSize_t simpleList;
vec vector;
};
int main()
{
// Some dummy values
_map theMap;
vec _key(4, 1);
_key[2] = 2;
vec _value(10,3);
_value[1] = 4;
theMap.emplace(_key, _value);
auto it = theMap.find(_key);
printf("Map: %lu %lu\n", it->second[0], it->second[1]);
complexList_t cmplxList;
std::list<vec> bins;
bins.push_back(_key);
std::list<size_t> cands;
cands.push_back(5);
auto _pair = std::make_pair(bins, cands);
cmplxList.push_back(_pair);
std::list<size_t> cand2;
cand2.push_back(6);
// This is okay
IntermediateResults im;
im.theMap = theMap;
im.cmplxList = cmplxList;
printf("imAf %lu %lu\n", im.theMap.size(), im.cmplxList.size());
it = im.theMap.find(_key);
printf("imMap: %lu %lu\n", it->second[0], it->second[1]);
// This however is not okay
IntermediateResults* imp = NULL;
imp = (IntermediateResults*) calloc(1, sizeof(*imp));
imp->theMap = theMap;
it = imp->theMap.find(_key);
printf("impMap: %lu %lu\n", it->second[0], it->second[1]);
imp->vector = _key;
printf("Still alive\n");
imp->simpleList = cand2; //This leads to segfault
imp->cmplxList = cmplxList; //This leads to segfault
printf("Dead\n");
return 0;
}
Output:
Map: 3 4
imAf 1 1
imMap: 3 4
impMap: 3 4
Map: 3 4
imAf 1 1
imMap: 3 4
impMap: 3 4
Still alive
The dummy output for the map looks okay. When I do the whole c++->python->c++ thing with only the map, it works beautifully. But when I use a 'simpler' type like vector/list it segfaults on assignment.
I really don't get it, what is the proper way to do it?