mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
core: fix leak when clearing dive log
46cf2fc086
fixed a bug where clearing of a divelog, such as the one
used for import, would erase dives in the global(!) divelog.
However, the new code used the function clear_dive_table(), which
only cleared the table without unregistering the dives. In particular,
the dives were not removed from the trips, which means that the trips
were not free()d.
This reinstates the old code, but now passes a divelog paremeter
to delete_single_dive() instead of accessing the global divelog.
Moreover, delete dives from the back to avoid unnecessary
copying.
An alternative and definitely simpler solution might be to just
add a "clear_trip_table()" after "clear_dive_table()".
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
8769b1232e
commit
e20ec9248c
5 changed files with 19 additions and 16 deletions
|
@ -767,18 +767,6 @@ struct dive *unregister_dive(int idx)
|
|||
return dive;
|
||||
}
|
||||
|
||||
/* this implements the mechanics of removing the dive from the global
|
||||
* dive table and the trip, but doesn't deal with updating dive trips, etc */
|
||||
void delete_single_dive(int idx)
|
||||
{
|
||||
struct dive *dive = get_dive(idx);
|
||||
if (!dive)
|
||||
return; /* this should never happen */
|
||||
remove_dive_from_trip(dive, divelog.trips);
|
||||
unregister_dive_from_dive_site(dive);
|
||||
delete_dive_from_table(divelog.dives, idx);
|
||||
}
|
||||
|
||||
void process_loaded_dives()
|
||||
{
|
||||
sort_dive_table(divelog.dives);
|
||||
|
@ -989,7 +977,7 @@ void add_imported_dives(struct divelog *import_log, int flags)
|
|||
/* Remove old dives */
|
||||
for (i = 0; i < dives_to_remove.nr; i++) {
|
||||
idx = get_divenr(dives_to_remove.dives[i]);
|
||||
delete_single_dive(idx);
|
||||
delete_single_dive(&divelog, idx);
|
||||
}
|
||||
dives_to_remove.nr = 0;
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ void clear_dive_file_data();
|
|||
void clear_dive_table(struct dive_table *table);
|
||||
void move_dive_table(struct dive_table *src, struct dive_table *dst);
|
||||
struct dive *unregister_dive(int idx);
|
||||
extern void delete_single_dive(int idx);
|
||||
extern bool has_dive(unsigned int deviceid, unsigned int diveid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -64,9 +64,24 @@ struct divelog &divelog::operator=(divelog &&log)
|
|||
return *this;
|
||||
}
|
||||
|
||||
/* this implements the mechanics of removing the dive from the
|
||||
* dive log and the trip, but doesn't deal with updating dive trips, etc */
|
||||
void delete_single_dive(struct divelog *log, int idx)
|
||||
{
|
||||
if (idx < 0 || idx > log->dives->nr) {
|
||||
report_info("Warning: deleting unexisting dive with index %d", idx);
|
||||
return;
|
||||
}
|
||||
struct dive *dive = log->dives->dives[idx];
|
||||
remove_dive_from_trip(dive, log->trips);
|
||||
unregister_dive_from_dive_site(dive);
|
||||
delete_dive_from_table(log->dives, idx);
|
||||
}
|
||||
|
||||
void divelog::clear()
|
||||
{
|
||||
clear_dive_table(dives);
|
||||
while (dives->nr > 0)
|
||||
delete_single_dive(this, dives->nr - 1);
|
||||
while (sites->nr)
|
||||
delete_dive_site(get_dive_site(0, sites), sites);
|
||||
if (trips->nr != 0) {
|
||||
|
|
|
@ -34,6 +34,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
void clear_divelog(struct divelog *);
|
||||
extern void delete_single_dive(struct divelog *, int idx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -363,7 +363,7 @@ void TestGitStorage::testGitStorageCloudMerge2()
|
|||
QCOMPARE(parse_file(cloudTestRepo.c_str(), &divelog), 0);
|
||||
process_loaded_dives();
|
||||
struct dive *dive = get_dive(1);
|
||||
delete_single_dive(1);
|
||||
delete_single_dive(&divelog, 1);
|
||||
QCOMPARE(save_dives("./SampleDivesMinus1.ssrf"), 0);
|
||||
git_local_only = true;
|
||||
QCOMPARE(save_dives(localCacheRepo.c_str()), 0);
|
||||
|
|
Loading…
Add table
Reference in a new issue