[PATCH 1/2] Make add_single_dive() grow the divelist allocation if necessary

Linus Torvalds torvalds at linux-foundation.org
Thu Oct 1 18:24:06 PDT 2015


From: Linus Torvalds <torvalds at linux-foundation.org>
Date: Thu, 1 Oct 2015 21:13:48 -0400
Subject: [PATCH 1/2] Make add_single_dive() grow the divelist allocation if necessary

We only made sure the divelist allocation was big enough in
"record_dive_to_table()", but add_single_dive() can add entries too.

Now, in practice that never bit anybody, since

 (a) we allocate extra entries anyway, and it would be very unusual that
     the divelist table was exactly full

 (b) most "malloc()" implementations end up having their own slop on top
     of that

 (c) add_single_dive() was only used for merging dives, which actually
     ends up removing more divex than it adds (but it does add one first)

but when I'm starting to split dives, this will be a bigger issue in
practice.  And it was wrong.

Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---
 divelist.c  | 17 +++++++++++++++++
 divelist.h  |  1 +
 parse-xml.c | 12 ++----------
 3 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/divelist.c b/divelist.c
index 3cbff84efe93..3cc0d2c8d5ff 100644
--- a/divelist.c
+++ b/divelist.c
@@ -767,9 +767,26 @@ void delete_single_dive(int idx)
 	free(dive);
 }
 
+struct dive **grow_dive_table(struct dive_table *table)
+{
+	int nr = table->nr, allocated = table->allocated;
+	struct dive **dives = table->dives;
+
+	if (nr >= allocated) {
+		allocated = (nr + 32) * 3 / 2;
+		dives = realloc(dives, allocated * sizeof(struct dive *));
+		if (!dives)
+			exit(1);
+		table->dives = dives;
+		table->allocated = allocated;
+	}
+	return dives;
+}
+
 void add_single_dive(int idx, struct dive *dive)
 {
 	int i;
+	grow_dive_table(&dive_table);
 	dive_table.nr++;
 	if (dive->selected)
 		amount_selected++;
diff --git a/divelist.h b/divelist.h
index bc3fd1af1b32..5bae09cff86e 100644
--- a/divelist.h
+++ b/divelist.h
@@ -22,6 +22,7 @@ extern char *get_dive_gas_string(struct dive *dive);
 
 extern dive_trip_t *find_trip_by_idx(int idx);
 
+struct dive **grow_dive_table(struct dive_table *table);
 extern int trip_has_selected_dives(dive_trip_t *trip);
 extern void get_dive_gas(struct dive *dive, int *o2_p, int *he_p, int *o2low_p);
 extern int get_divenr(struct dive *dive);
diff --git a/parse-xml.c b/parse-xml.c
index 9b223980dde3..a822395a7348 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -67,17 +67,9 @@ void clear_table(struct dive_table *table)
 void record_dive_to_table(struct dive *dive, struct dive_table *table)
 {
 	assert(table != NULL);
-	int nr = table->nr, allocated = table->allocated;
-	struct dive **dives = table->dives;
+	struct dive **dives = grow_dive_table(table);
+	int nr = table->nr;
 
-	if (nr >= allocated) {
-		allocated = (nr + 32) * 3 / 2;
-		dives = realloc(dives, allocated * sizeof(struct dive *));
-		if (!dives)
-			exit(1);
-		table->dives = dives;
-		table->allocated = allocated;
-	}
 	dives[nr] = fixup_dive(dive);
 	table->nr = nr + 1;
 }
-- 
2.4.2.387.gf86f31a



More information about the subsurface mailing list