Skip to content

Commit

Permalink
r.terraflow: Handle memory reallocation errors gracefully (#3970)
Browse files Browse the repository at this point in the history
Co-authored-by: Nicklas Larsson <n_larsson@yahoo.com>
  • Loading branch information
ShubhamDesai and nilason authored Aug 15, 2024
1 parent 0d5d274 commit 5b1a2a5
Showing 1 changed file with 34 additions and 14 deletions.
48 changes: 34 additions & 14 deletions raster/r.terraflow/unionFind.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@
#ifndef __UNION_FIND
#define __UNION_FIND

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>

extern "C" {
#include <grass/glocale.h>
}

/* initial range guesstimate */
#define UNION_INITIAL_SIZE 2000

Expand Down Expand Up @@ -68,11 +72,19 @@ unionFind<T>::unionFind()
{
maxsize = UNION_INITIAL_SIZE;
/* parent = new (long)[maxsize]; */
parent = (T *)calloc(maxsize, sizeof(T));
assert(parent);
if (void *new_parent = std::calloc(maxsize, sizeof(T))) {
parent = static_cast<T *>(new_parent);
}
else {
G_fatal_error(_("Not enough memory for %s"), "parent");
}
/* rank = new (long)[maxsize]; */
rank = (T *)calloc(maxsize, sizeof(T));
assert(rank);
if (void *new_rank = std::calloc(maxsize, sizeof(T))) {
rank = static_cast<T *>(new_rank);
}
else {
G_fatal_error(_("Not enough memory for %s"), "rank");
}
}

/************************************************************/
Expand Down Expand Up @@ -126,13 +138,21 @@ inline void unionFind<T>::makeSet(T x)
if (x >= maxsize) {
/* reallocate parent */
cout << "UnionFind::makeSet: reallocate double " << maxsize << "\n";
parent = (T *)realloc(parent, 2 * maxsize * sizeof(T));
assert(parent);
memset(parent + maxsize, 0, maxsize * sizeof(T));
/*reallocate rank */
rank = (T *)realloc(rank, 2 * maxsize * sizeof(T));
assert(rank);
memset(rank + maxsize, 0, maxsize * sizeof(T));
if (void *new_parent = std::realloc(parent, 2 * maxsize * sizeof(T))) {
parent = static_cast<T *>(new_parent);
std::memset(parent + maxsize, 0, maxsize * sizeof(T));
}
else {
G_fatal_error(_("Not enough memory for %s"), "parent");
}
/* reallocate rank */
if (void *new_rank = std::realloc(rank, 2 * maxsize * sizeof(T))) {
rank = static_cast<T *>(new_rank);
std::memset(rank + maxsize, 0, maxsize * sizeof(T));
}
else {
G_fatal_error(_("Not enough memory for %s"), "rank");
}
/*update maxsize */
maxsize *= 2;
}
Expand Down

0 comments on commit 5b1a2a5

Please sign in to comment.