将带有malloc指针的类放入映射容器中

时间:2011-08-14 06:27:47

标签: c++ stl

我想使用地图进行密钥/成员搜索,问题是该类包含malloc调用分配的缓冲区成员。

struct Key {
    int key1;
    int key2;
    bool operator < (Key & a) { .... } 
};

struct Entity {
    unsigned char *data; 
};

typedef std::map(Key, Entity) TMap;

然后我可以使用以下键来插入数据:

Tmap map;
Key key;
Entity ent;
ent.data = malloc(size);
key.key1 = xx;
key.key2 = xx;

map.insert( ...(key,ent));

问题是我希望删除地图时自动释放“ent.data”指针。同时,我希望在执行地图查找操作时可以访问“数据”来读取缓冲数据。

我尝试将析构函数添加到struct Entity中,但似乎它会导致一些重复的免费问题。

解决方案是什么?

[解决方法]: 1.使用shared_ptr:

typedef std::tr1:shared_ptr(unsigned char) CharPtr;

struct Entity {
  CharPtr data;
}

ent.data = CharPtr((unsigned char*)malloc(size), free);

或另一种解决方案。使用Vector作为Eugene Homyakov提到。

4 个答案:

答案 0 :(得分:6)

  1. 您应该在c ++中使用new而不是malloc
  2. 您应该在容器内使用 Smart pointers 而不是原始指针/裸指针。
  3. STL容器负责解除分配在freestore上分配的元素。这意味着您必须明确释放它们。实现这一目标的最佳方法是使用智能指针,使用智能指针,您不必显式释放动态内存,但元素本身负责释放自己的资源。

    C ++的 RAII / SBRM 功能专门用于避免问题,例如您所面临的问题。

答案 1 :(得分:3)

经典方法是在Entity中实现复制构造函数,赋值运算符和析构函数。还建议将分配代码放在Entity中。

但是,这里有更简单的解决方案:使用vector<unsigned char>而不是动态分配的内存:

struct Entity { std::vector<unsigned char> data; }
  • 您可以通过&data[0]
  • 访问内存
  • 保证向量的元素在内存中是线性的
  • 删除实体时会自动删除
  • 复制实体时将正确复制
  • 只需拨打data.resize(newsize)
  • 即可“分配”和“重新分配”

此外,您甚至不需要insert

Key key;
// initialize key
Entity& ent = map[key]; // automatically creates Entity for the key
// work with ent now 
ent.data.resize(bufferSize);
unsigned char* dataPtr = &ent.data[0];

答案 2 :(得分:1)

Entity需要包含一个指示已分配数据大小的成员。它还需要一个析构函数和一个复制构造函数。最好是添加几个成员函数来分配和释放data

struct Entity {
  Entity() : data_(NULL), length_(0) {}

  Entity( size_t length ) : data_(NULL), length_(0)
  { 
    allocate( length );
  }

  Entity( const Entity& other )
  {
    free();
    allocate( other.length );
    std::copy( other.data_, other.data_ + other.length_, data_ );
  }

  void allocate( size_t length )
  {
    free();
    data = malloc( length );
    if( data != NULL ) {
      length_ = length;
    }
  }

  void free()
  {
    if( length_ != 0 ) { 
      free( data_ ); 
    }
  }

  ~Entity() { free(); }

private:
  unsigned char *data_,
  size_t length_;
};

typdef std::map<struct Key, struct Entity> TMap;

您可能还希望提供访问器函数来检索指向Entity的数据和长度的指针。

最后,由于您使用的是C ++,因此不应使用原始指针。请考虑使用std::unique_ptr。此外,最好使用newdelete代替mallocfree

答案 3 :(得分:1)

一个简单的解决方案是将malloc - 指向unsigned char数组的指针替换为std::vector<unsigned char>。 Voilá,它只是有效。

PS1: 或者,当您显然提供自己的比较时,如果您定义了良好的比较运算符,它就会起作用。

PS2: 如果您绝对想要使用malloc,那么您可以定义自定义分配器并将其与std::vector一起使用;这是一个模板参数。

干杯&amp;第h。,