Details Ticket 869


Comment | Reply | Take | Open


Serial Number 869
Subject Possible memory leak in src/libes/vect32/Vlib/get_area.c:Vect_get_area_points()
Area bug
Queue grass
Requestors pcpa@conectiva.com.br
Owner none
Status resolved
Last User Contact Thu Dec 13 07:59:15 2001 (7 yr ago)
Current Priority 30
Final Priority 70
Due No date assigned
Last Action Thu Dec 13 08:02:27 2001 (7 yr ago)
Created Tue Dec 11 22:57:23 2001 (7 yr ago)

Transaction History Ticket 869


Tue, Dec 11 2001 22:57:23    Request created by guest  
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
Wed, Dec 12 2001 03:07:00    Mail sent by egm2@jps.net  
Return-Path <egm2@jps.net>
Delivered-To grass-bugs@lists.intevation.de
Date Tue, 11 Dec 2001 18:06:52 -0800
From "Eric G. Miller" <egm2@jps.net>
To Request Tracker <grass-bugs@intevation.de>
Cc grass5@grass.itc.it
Subject Re: [GRASS5] [bug #869] (grass) Possible memory leak in src/libes/vect32/Vlib/get_area.c:Vect_get_area_points()
Message-Id <20011211180652.61b5152c.egm2@jps.net>
In-Reply-To <20011211215723.B227A139D0@lists.intevation.de>
References <20011211215723.B227A139D0@lists.intevation.de>
X-Mailer Sylpheed version 0.6.5 (GTK+ 1.2.10; i386-debian-linux-gnu)
X-Face $}3V+uswm7Z!;4n|~VUONRE7}?M:)9EanJ+VSIbuLet]@F^~Fm^4{#&Ll9c[VT^L%tpnKL( y>h}_QRih0|V9"B(!y0Y.2R{i'sBKFXW+bn8(pJ2x]Te{Zqd^[YTj#e99&^K(5Wkp7Ie<d-V)**5%% B$08X%]!>l@&:_W<-CPN*&>qczh^'o
Mime-Version 1.0
Content-Type text/plain; charset=US-ASCII
Content-Transfer-Encoding 7bit
X-Spam-Status No, hits=1 required=5 tests=FROM_ENDS_IN_NUMS
On Tue, 11 Dec 2001 22:57:23 +0100 (CET), Request Tracker <grass-bugs@intevation.de>
wrote:

> 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()
[snip]
> 
>   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.

Yes, I think your correct about the memory leak.  The code should not assume
the line_struct is empty when it gets it.  I think you're also correct that
the right way to handle this is to use realloc() (if necessary) rather than
using free, as it could improve performance a little (especially when no
new memory is needed).

-- 
Eric G. Miller <egm2@jps.net>


Thu, Dec 13 2001 07:59:15    Mail sent by egm2@jps.net  
Return-Path <egm2@jps.net>
Delivered-To grass-bugs@lists.intevation.de
Date Wed, 12 Dec 2001 22:58:56 -0800
From Eric G.Miller <egm2@jps.net>
To grass5@grass.itc.it
Cc grass-bugs@intevation.de
Subject Re: [GRASS5] [bug #869] (grass) Possible memory leak in src/libes/vect32/Vlib/get_area.c:Vect_get_area_points()
Message-Id <20011212225856.053a11f9.egm2@jps.net>
In-Reply-To <20011211180652.61b5152c.egm2@jps.net>
References <20011211215723.B227A139D0@lists.intevation.de> <20011211180652.61b5152c.egm2@jps.net>
X-Mailer Sylpheed version 0.6.5 (GTK+ 1.2.10; i386-debian-linux-gnu)
X-Face $}3V+uswm7Z!;4n|~VUONRE7}?M:)9EanJ+VSIbuLet]@F^~Fm^4{#&Ll9c[VT^L%tpnKL( y>h}_QRih0|V9"B(!y0Y.2R{i'sBKFXW+bn8(pJ2x]Te{Zqd^[YTj#e99&^K(5Wkp7Ie<d-V)**5%% B$08X%]!>l@&:_W<-CPN*&>qczh^'o
Mime-Version 1.0
Content-Type text/plain; charset=US-ASCII
Content-Transfer-Encoding 7bit
X-Spam-Status No, hits=1 required=5 tests=FROM_ENDS_IN_NUMS
On Tue, 11 Dec 2001 18:06:52 -0800, "Eric G. Miller" <egm2@jps.net> wrote:

> On Tue, 11 Dec 2001 22:57:23 +0100 (CET), Request Tracker <grass-bugs@intevation.de>
wrote:
> 
> > 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()
> [snip]
> > 
> >   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]) ;
> > --

I committed a fix which just comments out the zeroing of BPoints->alloc_points.
The dig_alloc routines should then properly handle memory without there
being leakage.  There is other leakage still, but not so egregious...

-- 
Eric G. Miller <egm2@jps.net>


Thu, Dec 13 2001 08:02:27    Status changed to resolved by egmiller  
Comment | Reply | Take | Open

You are currently authenticated as guest.
[Show Configuration] [Login as another user]

Users Guide - Mail Commands - Homepage of RequestTracker 1.0.7 - list any request