[PATCH 2/5] Small changes in the memory management when dive-merging

Lubomir I. Ivanov neolit123 at gmail.com
Sun Dec 23 17:53:25 PST 2012


From: "Lubomir I. Ivanov" <neolit123 at gmail.com>

This patch makes a couple of modifications:
1) divelist.c:delete_single_dive() now tries to free all memory associated
with a dive, such as the string values for divemaster, location, notes &
etc.

2) dive.c:merge_text(), now always makes a copy in memory for the returned
string - either combined or one of the two which are passed
to the function.

The reason for the above two changes is that when (say) importing the same
data over and over, technically a merge will occur for the contained dives,
but mapped pointers can go out of scope.

main.c:report_dives() calls try_to_merge() and if succeeds the two dives
that were merged are deleted from the table. when we delete a dive,
we now make sure all string data is cleared with it, but also in the actual merge
itself, which precedes, copies of the merged texts are made (with merge_text()),
so that the new, resulted dive has his own text allocations.

Signed-off-by: Lubomir I. Ivanov <neolit123 at gmail.com>
---
 dive.c     |  9 +++++----
 divelist.c | 11 +++++++++++
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/dive.c b/dive.c
index a59bb5f..b5fb138 100644
--- a/dive.c
+++ b/dive.c
@@ -734,13 +734,14 @@ add_sample_b:
 static char *merge_text(const char *a, const char *b)
 {
 	char *res;
-
+	if (!a && !b)
+		return NULL;
 	if (!a || !*a)
-		return (char *)b;
+		return strdup(b);
 	if (!b || !*b)
-		return (char *)a;
+		return strdup(a);
 	if (!strcmp(a,b))
-		return (char *)a;
+		return strdup(a);
 	res = malloc(strlen(a) + strlen(b) + 9);
 	if (!res)
 		return (char *)a;
diff --git a/divelist.c b/divelist.c
index 16e0eaf..6be981d 100644
--- a/divelist.c
+++ b/divelist.c
@@ -1947,7 +1947,18 @@ void delete_single_dive(int idx)
 	dive_table.nr--;
 	if (dive->selected)
 		amount_selected--;
+	/* free all allocations */
 	free(dive->dc.sample);
+	if (dive->location)
+		free((void *)dive->location);
+	if (dive->notes)
+		free((void *)dive->notes);
+	if (dive->divemaster)
+		free((void *)dive->divemaster);
+	if (dive->buddy)
+		free((void *)dive->buddy);
+	if (dive->suit)
+		free((void *)dive->suit);
 	free(dive);
 }
 
-- 
1.7.11.msysgit.0



More information about the subsurface mailing list