gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master 58e3c12e: Table: adding new rows not changing


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 58e3c12e: Table: adding new rows not changing the column's gal_data_t pointer
Date: Wed, 22 Jun 2022 15:06:37 -0400 (EDT)

branch: master
commit 58e3c12e2a029d52e2b43395bb281f6d4a16f2ab
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Table: adding new rows not changing the column's gal_data_t pointer
    
    Until now, when adding new rows from another file, we were simply making a
    whole new table, copying the contents into that table and freeing the
    'gal_data_t' pointers of the original columns in the end.
    
    However, this caused a crash when the column pointers were being used in
    later steps (for example column arithmetic, which does its preparations in
    'ui.c', which include preserving the pointers to the columns): after adding
    new rows, the original 'gal_data_t' of the column was freed!
    
    With this commit, the 'gal_data_t' of the columns don't change after adding
    rows! We still do allocate a temporary 'gal_data_t', but instead of
    replacing the new 'gal_data_t', we simply free the contents, and replace
    with the new contents (thus preserving the 'gal_data_t').
    
    This fixes bug #62662.
---
 NEWS              |  2 ++
 bin/table/table.c | 38 ++++++++++++++++++++++++++------------
 2 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/NEWS b/NEWS
index 1088ee31..b306c303 100644
--- a/NEWS
+++ b/NEWS
@@ -140,6 +140,8 @@ See the end of the file for license conditions.
               called with '--output'. Reported by Raul Infante-Sainz.
   bug #62636: Table ignoring '--range' when '--head' is also
               called. Reported by Sepideh Eskandarlou.
+  bug #62662: Table crashes when column arithmetic is applied after adding
+              rows from another file (with '--catrowfile').
 
 
 
diff --git a/bin/table/table.c b/bin/table/table.c
index 0d7c3c2d..6802eb51 100644
--- a/bin/table/table.c
+++ b/bin/table/table.c
@@ -870,7 +870,7 @@ table_catrows_prepare(struct tableparams *p)
   char **strarr;
   char *hdu=NULL;
   int tableformat;
-  gal_data_t *tmp, *out=NULL;
+  gal_data_t *ocol, *tmp;
   size_t i, nrows=p->table->size;
   gal_list_str_t *filell, *hdull;
   size_t numcols, numrows, filledrows=p->table->size;
@@ -885,19 +885,23 @@ table_catrows_prepare(struct tableparams *p)
       nrows+=numrows;
     }
 
-  /* Allocate the new table with the necessary number of rows, then reverse
-     the newly allocated table (its columns were added in a
-     first-in-first-out list).*/
+  /* Change the 'array' component of each column (to preserve the column's
+     'gal_data_t' pointer; since previous preparations have kept that
+     pointer for next steps in some cases like column arithmetic). To do
+     this, we will first allocate a full 'gal_data_t', copy the contents,
+     free the contents of the original column, then replace them with the
+     larger array, and free the temporary 'gal_data_t'. */
   for(tmp=p->table; tmp!=NULL; tmp=tmp->next)
     {
-      /* Allocate the new column. */
-      gal_list_data_add_alloc(&out, NULL, tmp->type, 1, &nrows, NULL,
-                              0, p->cp.minmapsize, p->cp.quietmmap,
-                              tmp->name, tmp->unit, tmp->comment);
+      /* Allocate a temporary dataset (we just want its allocated space,
+         not the actual 'gal_data_t' pointer)! */
+      ocol=gal_data_alloc(NULL, tmp->type, 1, &nrows, NULL,
+                          0, p->cp.minmapsize, p->cp.quietmmap,
+                          tmp->name, tmp->unit, tmp->comment);
 
       /* Put the full contents of the existing column into the new
          column: this will be the first set of rows,  */
-      memcpy(out->array, tmp->array, tmp->size*gal_type_sizeof(tmp->type));
+      memcpy(ocol->array, tmp->array, tmp->size*gal_type_sizeof(tmp->type));
 
       /* If the column type is a string, we should set the input pointers
          to NULL to avoid freeing them later. */
@@ -906,12 +910,22 @@ table_catrows_prepare(struct tableparams *p)
           strarr=tmp->array;
           for(i=0;i<tmp->size;++i) strarr[i]=NULL;
         }
+
+      /* Free the contents of the current column (while keeping its
+         pointer), and replace those of the 'ocol' dataset. */
+      gal_data_free_contents(tmp);
+      tmp->comment=ocol->comment; ocol->comment=NULL;
+      tmp->array=ocol->array;     ocol->array=NULL;
+      tmp->dsize=ocol->dsize;     ocol->dsize=NULL;
+      tmp->name=ocol->name;       ocol->name=NULL;
+      tmp->unit=ocol->unit;       ocol->unit=NULL;
+      tmp->size=ocol->size;
+
+      /* Free the 'ocol' dataset. */
+      gal_data_free(ocol);
     }
-  gal_list_data_reverse(&out);
 
   /* Clean up and return. */
-  gal_list_data_free(p->table);
-  p->table=out;
   return filledrows;
 }
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]