[GRASS5] [bug #869] (grass) Possible memory leak in src/libes/vect32/Vlib/get_area.c:Vect_get_area_points()

Request Tracker grass-bugs at intevation.de
Tue Dec 11 16:57:23 EST 2001


this bug's URL: http://intevation.de/rt/webrt?serial_num=869
-------------------------------------------------------------------------

Subject: Possible memory leak in src/libes/vect32/Vlib/get_area.c:Vect_get_area_points()

Platform: Linux/Intel
Linux distro: Conectiva
linux cpu: Intel (i486, i586, pentium ...)
Xwindows version: Xfree 4.0.x
Xwindows manager: WindowMaker
TclTk version: tcl/tk 8.3
grass downloaded at: Hannover site
grass binary for platform: I compiled the sources myself
grass sources source: yes, I am using the latest GRASS from CVS
c compiler name: gcc


  I am using this (unfinished) code to draw vectors, from a "backend"
program that talks to a "frontend" gui program.

--
typedef struct _GrassVectInfo {
    char *name;			/* vector name */
    char *line, *fill;		/* last value used */
    char *mapset;
    int linecolor, fillcolor;	/* cached result */
    struct Map_info map;
    struct line_pnts *points;
} GrassVectInfo;

GrassVectInfo *GrassGetVector(char*);
void GrassDisplayVector(GrassVectInfo*, char*, char*);

static GrassVectInfo **vect_info;
static int num_vect_info;

GrassVectInfo *
GrassGetVector(char *name)
{
    int i;
    char *mapset;
    GrassVectInfo *info;

    /* check if vector not already loaded */
    for (i = 0; i < num_vect_info; i++)
	if (strcmp(name, vect_info[i]->name) == 0)
	    return (vect_info[i]);

    if ((mapset = G_find_file2("dig", name, "")) == NULL)
	return (NULL);

    if ((info = calloc(1, sizeof(GrassVectInfo))) == NULL)
	return (NULL);

    if (Vect_open_old(&info->map, name, mapset) < 2) {
	free(info);
	return (NULL);
    }

    info->name = strdup(name);
    info->mapset = strdup(mapset);

    /* XXX Vect_new_line_struct() vai chamar G_fatal_error
     * se não houver memória suficiente */
    info->points = Vect_new_line_struct();

    vect_info = realloc(vect_info, sizeof(GrassVectInfo*) *
			(num_vect_info + 1));
    vect_info[num_vect_info++] = info;

    return (info);
}

void
GrassDisplayVector(GrassVectInfo *info, char *line, char *fill)
{
    int i;
    double *x, *y;
    struct Cell_head window;

    Vect_rewind(&info->map);

    R_open_driver();
    D_setup(0);

    G_get_set_window(&window);

    G_setup_plot(D_get_d_north(), D_get_d_south(),
		 D_get_d_west(), D_get_d_east(),
		 D_move_abs, D_cont_abs);

    Vect_set_constraint_region(&info->map, window.north, window.south,
			       window.east, window.west);

    /* preenche polígonos */
    if (info->fill == NULL || strcmp(info->fill, fill)) {
	free(info->fill);
	info->fill = strdup(fill);
	info->fillcolor = D_translate_color(info->fill);
    }

    if (strcmp(info->fill, "none") != 0) {
	int npoints;
	int line, nlines;
	double N, S, E, W;

	R_standard_color(info->fillcolor);

	nlines = V2_num_areas(&info->map);
	for (line = 1; line <= nlines; line++) {
	    if (Vect_get_area_points(&info->map, line, info->points) < 0)
		break;

	    V2_get_area_bbox(&info->map, line, &N, &S, &E, &W);
	    if (S > window.north || N < window.south ||
		W > window.east || E < window.west)
		continue;

	    G_plot_polygon(info->points->x, info->points->y,
			   info->points->n_points);
	}

	Vect_rewind(&info->map);
    }

    /* desenha contorno */
    if (info->line == NULL || strcmp(info->line, line)) {
	free(info->line);
	info->line = strdup(line);
	info->linecolor = D_translate_color(info->line);
    }
    R_standard_color(info->linecolor);

    for (;;) {
        if (Vect_read_next_line(&info->map, info->points) < 0)
	    break;
	x = info->points->x;
	y = info->points->y;
	for (i = 1; i < info->points->n_points; i++, x++, y++)
	    G_plot_line(x[0], y[0], x[1], y[1]);
    }

    R_close_driver();
}
--

  The problem is the code

--
  BPoints->n_points = 0;
  BPoints->alloc_points = 0;
  Area =  &(Map->Area[area]) ;
--

in Vect_get_area_points(), if I replace it by

--
  G_free(BPoints->x);
  G_free(BPoints->y);
  BPoints->n_points = 0;
  BPoints->alloc_points = 0;
  Area =  &(Map->Area[area]) ;
--

the problem seens to go away.

  I am testing it with maps with more than 64k polygons, and with the patch,
memory usage seens constant, when running the sample GrassDisplayVector
function several times. I believe a better aproach should be done to fix
the problem, as it is not really required to free the memory to just
reallocate it in the code below, but I preferred to not change the logic
of the code in the sample fix.

Paulo


-------------------------------------------- Managed by Request Tracker



More information about the grass-dev mailing list