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
|
|
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>
|
|
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>
|
|