C++ 将稀疏散列映射序列化到文件时出现问题

C++ 将稀疏散列映射序列化到文件时出现问题,c++,serialization,C++,Serialization,这是我将稀疏散列映射char*const,int序列化到文件中的代码,注意map.key类型是char*const,这是必需的。如果没有,编译器报告找不到匹配的函数。这就是问题发生的地方,因为我无法为char*const类型的变量分配内存,在为其分配足够的内存之前,如何将序列化文件中的数据读取到map.key中?或者,除此之外,还有其他方法可以序列化稀疏散列映射字符*常量int吗 #include <iostream> #include <sparsehash/sparse_h

这是我将稀疏散列映射char*const,int序列化到文件中的代码,注意map.key类型是char*const,这是必需的。如果没有,编译器报告找不到匹配的函数。这就是问题发生的地方,因为我无法为char*const类型的变量分配内存,在为其分配足够的内存之前,如何将序列化文件中的数据读取到map.key中?或者,除此之外,还有其他方法可以序列化稀疏散列映射字符*常量int吗

#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 * const, int>* value) const {
    // this can't be done, since value->first is of type 'char *const'
    // value->first = realloc(value->first, SIZE);
    if (fread(const_cast<char *>(value->first), 1, SIZE, 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<char * const, int>& value) const {
    if (fwrite(value.first, 1, SIZE, 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(SIZE);
  p2 = (char *) malloc(SIZE);
  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;
  // cout << old_map[p2] << 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;
}

这个程序可以编译,但当我运行它时,它告诉我segmentation fault 11,gdb调试结果显示memcpy.S:没有这样的文件或目录,任何帮助都将不胜感激

首先回答OP关于char*真的那么糟糕的问题

与std::string相比,char*大大增加了您的工作量。首先,不需要malloc和free,顺便说一句,你不是在做free。尺寸和大小调整已为您完成。事实上,所有的内存管理都是为您处理的,除非您使用指向std::strings的指针。strcpy及其附带的所有溢出检查变为=。拆分、搜索和排序功能是内置的,如果需要的话。非常方便的小家伙,std::strings

作为容器密钥,您可能无法控制销毁逻辑。该对将被销毁,指针也将随之销毁,但指向的内存仍将存在,需要释放,但您不再拥有可以调用free的指针

您可以在对的析构函数触发并销毁指针之前释放内存,但随后必须保护代码中销毁对的所有点。既然可以为您完成,为什么还要忍受头痛和跟踪代码分散在您的程序中呢

问题

bool operator()(FILE* fp, std::pair<char * const, int>* value) const {
  // this can't be done, since value->first is of type 'char *const'
  // value->first = realloc(value->first, SIZE);
  if (fread(const_cast<char *>(value->first), 1, SIZE, fp) != 1) {
    return false;
  }

  if (fread(&(value->second), sizeof(value->second), 1, fp) != 1)
    return false;
  return true;
}
Buf是在堆栈上分配的,因此当它超出范围时将被销毁,但此时它已被复制到字符串中。如果buf是以保证为null的方式存储的,则可能不需要将其设为null


错误消息memcpy.S:没有这样的文件或目录是GDB试图显示失败的行,并且无法找到包含memcpy函数的源文件。segfault值得担心,因为源文件丢失了,而不是那么重要。bug在调用memcpy之前的某个地方。检查堆栈跟踪以找到您的最后一行代码,并在那里开始调查。

Woah Woah Woah。。。char*作为容器密钥?strcpy?马洛克????这是C++和2015,伙计!std::string。使用std::string,这样生活会简单得多。只是好奇,char*不能是容器密钥吗?真的那么糟糕吗?
  char buf[size+1]; // +1 for null char
  int len = fread(buf, 1, SIZE, fp)
  if (len != 1) {
    return false;
  }
  buf[len] = '0\'; //terminate string with null
  value->first = buf;