我想使用地图进行密钥/成员搜索,问题是该类包含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提到。
答案 0 :(得分:6)
new
而不是malloc
。 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
。此外,最好使用new
和delete
代替malloc
和free
。
答案 3 :(得分:1)
一个简单的解决方案是将malloc
- 指向unsigned char
数组的指针替换为std::vector<unsigned char>
。 Voilá,它只是有效。
PS1: 或者,当您显然提供自己的比较时,如果您定义了良好的比较运算符,它就会起作用。
PS2:
如果您绝对想要使用malloc
,那么您可以定义自定义分配器并将其与std::vector
一起使用;这是一个模板参数。
干杯&amp;第h。,