From 38ec2d7e00be680cfb41f51f328733d91fc3a2cf Mon Sep 17 00:00:00 2001 From: Paul Wessel Date: Mon, 19 Jun 2023 11:13:42 +0200 Subject: [PATCH] Do no free external trailing text strings See https://github.com/GenericMappingTools/pygmt/issues/2524 for background. Sees we are trying to free strings thar belong to Python and not GMT. However, not solved yet. --- src/gmt_api.c | 3 ++- src/gmt_hidden.h | 3 ++- src/gmt_io.c | 16 +++++++++------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/gmt_api.c b/src/gmt_api.c index 306c443c2c5..63135be9c28 100644 --- a/src/gmt_api.c +++ b/src/gmt_api.c @@ -4127,6 +4127,7 @@ GMT_LOCAL struct GMT_DATASET * gmtapi_import_dataset (struct GMTAPI_CTRL *API, i S->data[col_pos_out] = V_obj->data[col_pos].f8; SH->alloc_mode[col_pos_out] = GMT_ALLOC_EXTERNALLY; /* Not this objects job to free what was passed in by reference */ } + SH->alloc_mode_text = GMT_ALLOC_EXTERNALLY; /* Not this object's job to free what was passed in by reference */ DH = gmt_get_DD_hidden (D_obj); if (smode) S->text = V_obj->text; /* Hook up trailing text array */ gmtapi_increment_d (D_obj, V_obj->n_rows, n_columns, 1U); /* Update counters for D_obj with 1 segment */ @@ -4520,7 +4521,7 @@ GMT_LOCAL int gmtapi_export_dataset (struct GMTAPI_CTRL *API, int object_ID, uns } if (S->text) { V_obj->text = S->text; - VH->alloc_mode_text = GMT_ALLOC_EXTERNALLY; /* Since not duplicated, just pointed to */ + VH->alloc_mode_text = SH->alloc_mode_text = GMT_ALLOC_EXTERNALLY; /* Since not duplicated, just pointed to */ } V_obj->n_rows = n_rows; VH->alloc_level = S_obj->alloc_level; /* Otherwise D_obj will be freed before we get to use data */ diff --git a/src/gmt_hidden.h b/src/gmt_hidden.h index 2614e4a1fd9..3fcb69b4e21 100644 --- a/src/gmt_hidden.h +++ b/src/gmt_hidden.h @@ -79,7 +79,8 @@ struct GMT_DATASEGMENT_HIDDEN { /* Supporting information hidden from the API double lat_limit; /* For polar caps: the latitude of the point closest to the pole */ struct GMT_OGR_SEG *ogr; /* NULL unless OGR/GMT metadata exist for this segment */ struct GMT_DATASEGMENT *next; /* NULL unless polygon and has holes and pointing to next hole */ - enum GMT_enum_alloc *alloc_mode; /* Allocation mode per column [GMT_ALLOC_INTERNALLY] */ + enum GMT_enum_alloc *alloc_mode; /* Allocation mode per data column [GMT_ALLOC_INTERNALLY] */ + enum GMT_enum_alloc alloc_mode_text; /* Allocation mode for trailing text column [GMT_ALLOC_INTERNALLY] */ char *file[2]; /* Name of file or source [0 = in, 1 = out] */ }; diff --git a/src/gmt_io.c b/src/gmt_io.c index 159d2b09cca..56f659df70d 100644 --- a/src/gmt_io.c +++ b/src/gmt_io.c @@ -8795,13 +8795,15 @@ struct GMT_DATASET * gmt_transpose_dataset (struct GMT_CTRL *GMT, struct GMT_DAT return (Dt); } -GMT_LOCAL void gmtio_free_segment_text (struct GMT_CTRL *GMT, struct GMT_DATASEGMENT *S) { - /* Frees any array of trailing text items */ +GMT_LOCAL void gmtio_free_segment_text (struct GMT_CTRL *GMT, struct GMT_DATASEGMENT *S, struct GMT_DATASEGMENT_HIDDEN *SH) { + /* Frees any array of trailing text items unless externally allocated */ uint64_t row; - if (S->text == NULL) return; /* No text */ - for (row = 0; row < S->n_rows; row++) - gmt_M_str_free (S->text[row]); - gmt_M_free (GMT, S->text); + if (S->text == NULL) return; /* No trailing text array */ + if (SH->alloc_mode_text == GMT_ALLOC_INTERNALLY) { /* We can free these strings */ + for (row = 0; row < S->n_rows; row++) + gmt_M_str_free (S->text[row]); + } + gmt_M_free (GMT, S->text); /* Always free the array holding the strings */ } /*! . */ @@ -8825,7 +8827,7 @@ void gmt_free_segment (struct GMT_CTRL *GMT, struct GMT_DATASEGMENT **S) { gmt_M_str_free ( segment->header); for (k = 0; k < 2; k++) gmt_M_str_free (SH->file[k]); if (SH->ogr) gmtio_free_ogr_seg (GMT, segment); /* OGR metadata */ - gmtio_free_segment_text (GMT, segment); + gmtio_free_segment_text (GMT, segment, SH); gmt_M_free (GMT, SH->alloc_mode); gmt_M_free (GMT, segment->hidden); gmt_M_free (GMT, segment);