У меня есть коллекция полигонов, которые я извлекаю из базы данных и хочу сохранить в двоичном дереве для быстрого доступа. В качестве бинарного дерева я использую std::map.
Я создал это решение, которое описано ниже, но я думаю, что это неправильно, потому что я не вызываю free() для освобождения памяти, выделенной malloc().
Мои вопросы (проблемы):
- Правильно ли использовать std::map, если мне нужно только вставлять и получать доступ к элементам этой карты? Я просто хочу быстро найти геометрию по ее идентификатору.
- В std::map я храню указатели на геометрии вместо хранения самих геометрий. Это хорошая идея? Раньше я пытался хранить сами геометрии, но потом понял, что std::map делает копию объекта, что создавало проблемы.
- В методе ConvertSpatial2GPC(..) я создаю объекты gpc_geometry, которые создают ссылки, которые я выпускаю в gpc_free_polygon(..). Но я не могу выпустить сам объект gpc_geometry, потому что у меня нет ссылки на него на тот момент.
Я использую следующие структуры:
typedef struct /* Polygon vertex structure */
{
double x; /* Vertex x component */
double y; /* vertex y component */
} gpc_vertex;
typedef struct /* Vertex list structure */
{
int num_vertices; /* Number of vertices in list */
gpc_vertex *vertex; /* Vertex array pointer */
} gpc_vertex_list;
typedef struct /* Polygon set structure */
{
int num_contours; /* Number of contours in polygon */
int *hole; /* Hole / external contour flags */
gpc_vertex_list *contour; /* Contour array pointer */
} gpc_polygon;
typedef std::map<long, gpc_polygon*> layer;
Мой рабочий процесс выглядит следующим образом:
- Загружать элементы из базы данных
- Вызовите метод initializeLayer(), который возвращает слой (см. предыдущее определение типа)
- ... Работа со слоем...
- Вызовите метод freeLayer(), чтобы освободить память, используемую слоем.
Код для инициализации объектов геометрии:
layer initializeLayer() {
//... database connection code
//find the count of objects in database
int count = ...
//helper object for loading from database
spatial_obj* sp_obj = NULL;
//initialize a array to hold the objects
gpc_polygon* gpc_objects;
gpc_objects = (gpc_polygon*)malloc(sizeof(gpc_polygon) * count);
layer myLayer;
int i = 0;
//... query database
while(db.Fetch()) {
id = db.GetLongData(0);
db.GetSDO_Object(&sp_obj); //load from database
db.ConvertSpatial2GPC(sp_obj, &gpc_mullad[i]); //convert polygon to GPC format
//insert a pair (ID->pointer to the geometry)
myLayer.insert(layer::value_type(id, &gpc_objects[i]);
i++;
}
return layer;
}
Код для освобождения слоя:
void freeLayer(layer myLayer) {
for (layer::iterator it = myLayer.begin(); it != myLayer.end(); ++it) {
gpc_free_polygon(it->second); //frees the memory from this geometry object
}
}
Код для освобождения объекта геометрии:
void gpc_free_polygon(gpc_polygon *p)
{
int c;
for (c= 0; c < p->num_contours; c++) {
FREE(p->contour[c].vertex);
FREE(p->hole);
FREE(p->contour);
p->num_contours= 0;
}
malloc
. Найдитеstd::vector
. - person user694733   schedule 05.11.2014new/delete
и, наконец, указатели сmalloc/free
используйте только в случае необходимости. - person user694733   schedule 06.11.2014