I wrote some kind of index and I am trying to use it. When I run the program in debug mode everything seems to be fine, but in release mode the program exits with code -1073741819 (hex: FFFFFFFFC0000005); this seems to be an access violation.
The code uses data type unsigned __int128. When I replace this by uint64_t the program works also in release mode. I am not sure, but using templates could also play a role. And even commenting out a function call (FindAllByFirstID in SomeFunc) that is never reached leads to seemingly correct execution in release mode.
I am not experienced in C++. Perhaps I overlook something. But my guess is that there is something overridden by the big datatype __int128. Maybe something can't deal with that type?
Can someone please help?
Unfortunately I was not able to even more shorten the code. (I know, in this form it makes little sense, but nevertheless it should execute correctly.)
#include <map>
#include <string>
#include <vector>
using namespace std;
#define ID_t unsigned __int128
struct __attribute__ ((packed)) DATA_t {
ID_t tid;
union {
array<uint16_t, 0> a;
uint8_t aDummy[4];
} data;
array<ID_t, 2> id;
};
template<class I>
class Entry {
public:
I data;
Entry<I>() {};
Entry<I>(const Entry<I>& orig) {};
virtual ~Entry<I>() {};
private:
};
template<class I>
struct ID_cmp {
bool operator()(const I& a, const I& b) const {
return a.id < b.id;
}
};
template<class I>
struct DATA_cmp {
bool operator()(const I& a, const I& b) const {
return a.data.a < b.data.a;
}
};
template<class I> class Index;
template<class I>
class IndexData {
public:
IndexData(Index<I>* index) : index(index) {};
IndexData(const IndexData<I>& orig) {};
virtual ~IndexData() {};
bool InsertOrFindEntry(Entry<I>** entry) {
if (!entries) {
entries = new map<I, Entry<I>*, DATA_cmp < I >> ();
Entry<I> modEntry;
modEntry.data = (*entry)->data;
index->CreateEntry(&modEntry.data);
}
auto search = entries->find((*entry)->data);
if (search == entries->end()) {
entries->operator[]((*entry)->data) = *entry;
return true;
} else {
delete *entry;
*entry = search->second;
return false;
}
};
Entry<I>* FindEntry(const I* data) {
if (entries) {
auto entry = entries->find(*data);
return entry == entries->end() ? nullptr : entry->second;
}
return nullptr;
};
void PushAllEntries(vector<Entry<I>*>& datas) {
if (entries) for (const auto& e : *entries) datas.push_back(e.second);
};
private:
Index<I>* index;
map<I, Entry<I>*, DATA_cmp<I>>* entries = nullptr;
};
template<class I>
class IndexID {
public:
IndexID(Index<I>* index) {
this->index = new IndexData<I>(index);
};
IndexID(const IndexID<I>& orig) {};
virtual ~IndexID() {};
bool InsertOrFindEntry(Entry<I>** entry) {
return index->InsertOrFindEntry(entry);
};
Entry<I>* FindEntry(const I* data) {
return index->FindEntry(data);
};
void PushAllEntries(vector<Entry<I>*>& datas) {
if (index) index->PushAllEntries(datas);
};
private:
IndexData<I>* index = nullptr;
};
class IndexCommon {
public:
IndexCommon() {};
IndexCommon(const IndexCommon& orig) {};
virtual ~IndexCommon() {};
virtual void SomeFunc(void* entry) {};
private:
};
template<class I>
class Index : public IndexCommon {
public:
Index() {};
Index(const Index<I>& orig) {};
virtual ~Index() {};
bool InsertOrGetEntry(Entry<I>** entry) {
IndexID<I>* indexID = GetIndexID(&(*entry)->data);
return indexID->InsertOrFindEntry(entry);
};
Entry<I>* CreateEntry(const void* data) {
Entry<I>* entry = new Entry<I>();
entry->data = *(I*) data;
if (InsertOrGetEntry(&entry)) SomeFuncCreate(entry);
return entry;
};
void FindAllByFirstID(const ID_t id, vector<Entry<I>*>& datas);
void SomeFuncCreate(Entry<I>* entry);
void SomeFunc(void* entry) override;
private:
map<I, IndexID<I>*, ID_cmp<I>> indexID;
IndexID<I>* GetIndexID(const I* data) {
auto search = indexID.find(*data);
if (search == indexID.end()) {
IndexID<I>* idxID = new IndexID<I>(this);
indexID[*data] = idxID;
return idxID;
}
return search->second;
};
};
template <class I>
inline void Index<I>::FindAllByFirstID(const ID_t uid, vector<Entry<I>*>& datas) {
DATA_t search;
search.id[0] = uid;
search.id[1] = 0;
auto lower = indexID.lower_bound(search);
search.id[1] = UINT64_MAX;
auto upper = indexID.upper_bound(search);
if (lower == indexID.end()) return;
for (auto it = lower; it != upper; ++it) (*it).second->PushAllEntries(datas);
}
template<class I>
inline void Index<I>::SomeFuncCreate(Entry<I>* entry) {
vector<Entry<I>*> datas;
FindAllByFirstID(entry->data.id[1], datas);
}
template<class I>
inline void Index<I>::SomeFunc(void* entry) {
vector<Entry<I>*> datas;
FindAllByFirstID(((Entry<I>*)entry)->data.id[1], datas);
}
int main(int argc, char** argv) {
Index<DATA_t> myIndex = Index<DATA_t>();
Entry<DATA_t>* myEntry = new Entry<DATA_t>();
myIndex.InsertOrGetEntry(&myEntry);
return 0;
}
I work with Netbeans 11.1 on Win10, with MSYS_NT-10.0-19041.
I tried to shorten the code as far as possible, commented out every function and so on. I hoped, I could encircle the problem but it didn't really work it. If I remove to much of the code it works. All in all the behaviour seems to me to be not comprehensible.