0

I tried to code to serialize the type of sparse_hash_map to file, but somehow it just didn't work, compelling it tells me this error message:

/usr/local/include/sparsehash/sparsetable:1763:13: error: no matching function for call to object of type 'CharPointerToIntSerializer'

  if ( !serializer(fp, &*it) )  return false;

        ^~~~~~~~~~

it seems that mymap.serialize method works just fine, it's mymap2.unsirialize method that fails, any ideas about problems in this codes below?

#include <iostream>
#include <sparsehash/sparse_hash_map>
using google::sparse_hash_map;      // namespace where class lives by default

using namespace std;

#define SIZE 13

struct CharPointerToIntSerializer {
  bool operator()(FILE* fp, std::pair<char *, int>* value) const {
    if (fread(value->first, SIZE, 1, fp) != 1) {
      return false;
    }
    if (fread(&(value->second), sizeof(value->second), 1, fp) != 1)
      return false;
    return true;
  }

  // bool operator()(FILE* fp, const std::pair<const char *, int>& value) const {
  bool operator()(FILE* fp, const std::pair<char *, int>& value) const {
    for(int i = 0; i < SIZE; i++){
      if (fwrite(value.first + i, 1, 1, fp) != 1)
    return false;
    }

    if (fwrite(&value.second, sizeof(value.second), 1, fp) != 1)
      return false;
    return true;
  }
};

int main(){
  sparse_hash_map<char*, int> old_map,new_map;
  char *p1, *p2;
  p1 = (char *) malloc(10);
  p2 = (char *) malloc(10);
  strcpy(p1, "hello");
  strcpy(p2, "world");
  old_map[p1] = 1;
  old_map[p2] = 2;

  FILE* fp = fopen("hashtable.txt", "w");
  old_map.serialize(CharPointerToIntSerializer(), fp);
  cout << old_map[p1] << endl;
  fclose(fp);

  FILE* fp_in = fopen("hashtable.txt", "r");
  new_map.unserialize(CharPointerToIntSerializer(), fp_in);
  fclose(fp_in);
  assert(old_map == new_map);
  cout << new_map[p2] << endl;
}
beanmoon
  • 59
  • 2
  • 8

1 Answers1

0

The value_type of the sparse map is std::pair<K const, V>. So,

bool operator()(FILE* fp, std::pair<char*, int>* value) const;
bool operator()(FILE* fp, std::pair<char*, int> const& value) const;

should be

bool operator()(FILE* fp, std::pair<char* const, int>* value) const;
bool operator()(FILE* fp, std::pair<char* const, int> const& value) const;

respectively.

That compiles, against sparsehash 1.12 (Ubuntu comes with v1.10 packaged!)

sehe
  • 374,641
  • 47
  • 450
  • 633
  • I did change my codes as you pointed, it compiles :) great work here. but when i run the program, it prints "Segmentation fault: 11" error, is there something wrong with my serialization method? huh, really got myself stuck in here, thanks for your help~ – beanmoon May 28 '15 at 15:12
  • Yup. There's something wrong. (Don't do the raw pointers. Don't hardcode magic `SIZE`s. Etc. It's hard to not write bugs with those things) – sehe May 28 '15 at 15:19
  • I think there's something wrong when try to unserialize the map, because the type of map key is 'char * const' which can't not be allocated enough memory before we read data from serialization file into the map, so segmentation fault occurs. gdb debug result verified it, too. so is there anyway to read data into map.key (aka. type of 'char * const')? – beanmoon May 28 '15 at 16:38