0

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.

lxndr
  • 85
  • 4

0 Answers0