summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2019-07-06 14:41:09 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2019-07-06 11:23:35 -0700
commit69be1e23f231081e6bad98903c10782faf5104a7 (patch)
treebf8ca85183983f6adebd494c59c80663cb33f48c
parent5e9ffe30053454ef9d058c7e7d41f55508cb66d7 (diff)
downloadsubsurface-69be1e23f231081e6bad98903c10782faf5104a7.tar.gz
Cleanup: fix memory management of the plot data
There was a global variable last_pi_entry_new, which stored the recently allocated plot data. This was freed when new plot data was generated. A very scary proposition: You can never have two plot datas at the same time! But exactly that happens when you export for example subtitles. The only reason why this didn't lead to very crazy behavior is that at least on my Linux machine, the calloc() call would just return the previously freed memory. Fix this mess by removing the global variable and freeing the data in the callers. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r--core/profile.c20
-rw-r--r--core/profile.h2
-rw-r--r--core/save-profiledata.c4
-rw-r--r--profile-widget/profilewidget2.cpp1
4 files changed, 16 insertions, 11 deletions
diff --git a/core/profile.c b/core/profile.c
index 3016f2af8..5f8be02ac 100644
--- a/core/profile.c
+++ b/core/profile.c
@@ -31,8 +31,6 @@ extern int ascent_velocity(int depth, int avg_depth, int bottom_time);
struct dive *current_dive = NULL;
unsigned int dc_number = 0;
-static struct plot_data *last_pi_entry_new = NULL;
-
#ifdef DEBUG_PI
/* debugging tool - not normally used */
static void dump_pi(struct plot_info *pi)
@@ -507,7 +505,13 @@ struct plot_info calculate_max_limits_new(struct dive *dive, struct divecomputer
entry++; \
idx++
-struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
+void free_plot_info_data(struct plot_info *pi)
+{
+ free(pi->entry);
+ pi->entry = NULL;
+}
+
+static void populate_plot_entries(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
{
UNUSED(dive);
int idx, maxtime, nr, i;
@@ -529,7 +533,7 @@ struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *
plot_data = calloc(nr, sizeof(struct plot_data));
pi->entry = plot_data;
if (!plot_data)
- return NULL;
+ return;
pi->nr = nr;
idx = 2; /* the two extra events at the start */
@@ -634,8 +638,6 @@ struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *
plot_data[idx++].sec = lasttime + 1;
plot_data[idx++].sec = lasttime + 2;
pi->nr = idx;
-
- return plot_data;
}
#undef INSERT_ENTRY
@@ -1334,9 +1336,7 @@ void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plo
#else
UNUSED(planner_ds);
#endif
- /* Create the new plot data */
- free((void *)last_pi_entry_new);
-
+ free_plot_info_data(pi);
get_dive_gas(dive, &o2, &he, &o2max);
if (dc->divemode == FREEDIVE){
pi->dive_type = FREEDIVE;
@@ -1349,7 +1349,7 @@ void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plo
pi->dive_type = AIR;
}
- last_pi_entry_new = populate_plot_entries(dive, dc, pi);
+ populate_plot_entries(dive, dc, pi);
check_setpoint_events(dive, dc, pi); /* Populate setpoints */
setup_gas_sensor_pressure(dive, dc, pi); /* Try to populate our gas pressure knowledge */
diff --git a/core/profile.h b/core/profile.h
index b0828c48f..125e349a8 100644
--- a/core/profile.h
+++ b/core/profile.h
@@ -75,11 +75,11 @@ struct ev_select {
struct plot_info calculate_max_limits_new(struct dive *dive, struct divecomputer *given_dc);
void compare_samples(struct plot_data *e1, struct plot_data *e2, char *buf, int bufsize, int sum);
-struct plot_data *populate_plot_entries(struct dive *dive, struct divecomputer *dc, struct plot_info *pi);
struct plot_info *analyze_plot_info(struct plot_info *pi);
void create_plot_info_new(struct dive *dive, struct divecomputer *dc, struct plot_info *pi, bool fast, struct deco_state *planner_ds);
void calculate_deco_information(struct deco_state *ds, const struct deco_state *planner_de, const struct dive *dive, const struct divecomputer *dc, struct plot_info *pi, bool print_mode);
struct plot_data *get_plot_details_new(struct plot_info *pi, int time, struct membuffer *);
+void free_plot_info_data(struct plot_info *pi);
/*
* When showing dive profiles, we scale things to the
diff --git a/core/save-profiledata.c b/core/save-profiledata.c
index 09ac76886..d999d4b49 100644
--- a/core/save-profiledata.c
+++ b/core/save-profiledata.c
@@ -191,6 +191,7 @@ static void put_st_event(struct membuffer *b, struct plot_data *entry, int offse
}
put_format(b, "\n");
}
+
static void save_profiles_buffer(struct membuffer *b, bool select_only)
{
int i;
@@ -211,6 +212,7 @@ static void save_profiles_buffer(struct membuffer *b, bool select_only)
put_format(b, "\n");
}
put_format(b, "\n");
+ free_plot_info_data(&pi);
}
}
@@ -233,6 +235,8 @@ void save_subtitles_buffer(struct membuffer *b, struct dive *dive, int offset, i
put_st_event(b, &pi.entry[i], offset, length);
}
put_format(b, "\n");
+
+ free_plot_info_data(&pi);
}
int save_profiledata(const char *filename, const bool select_only)
diff --git a/profile-widget/profilewidget2.cpp b/profile-widget/profilewidget2.cpp
index f117dc450..f377eeb8e 100644
--- a/profile-widget/profilewidget2.cpp
+++ b/profile-widget/profilewidget2.cpp
@@ -636,6 +636,7 @@ void ProfileWidget2::plotDive(const struct dive *d, bool force, bool doClearPict
* shown.
*/
+ free_plot_info_data(&plotInfo);
plotInfo = calculate_max_limits_new(&displayed_dive, currentdc);
#ifndef SUBSURFACE_MOBILE
create_plot_info_new(&displayed_dive, currentdc, &plotInfo, !shouldCalculateMaxDepth, &DivePlannerPointsModel::instance()->final_deco_state);