]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
factor,tail: avoid quadratic reallocation
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 23 Sep 2023 08:15:08 +0000 (01:15 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 23 Sep 2023 08:15:50 +0000 (01:15 -0700)
* src/factor.c (struct mp_factors): New member nalloc.
(mp_factor_init): Initialize it.
* src/factor.c (mp_factor_insert):
* src/tail.c (parse_options): Use xpalloc to avoid quadratic
worst-case behavior on reallocation.
* src/tail.c (pids_alloc): New static var.

src/factor.c
src/tail.c

index c47250a488b9b4c91b51c995904dade87b46357d..8848ac2ac603e3181e11fe022bfab6a04a861e38 100644 (file)
@@ -247,6 +247,7 @@ struct mp_factors
   mpz_t             *p;
   unsigned long int *e;
   idx_t nfactors;
+  idx_t nalloc;
 };
 
 static void factor (uintmax_t, uintmax_t, struct factors *);
@@ -595,6 +596,7 @@ mp_factor_init (struct mp_factors *factors)
   factors->p = nullptr;
   factors->e = nullptr;
   factors->nfactors = 0;
+  factors->nalloc = 0;
 }
 
 static void
@@ -624,11 +626,14 @@ mp_factor_insert (struct mp_factors *factors, mpz_t prime)
 
   if (i < 0 || mpz_cmp (p[i], prime) != 0)
     {
-      p = xireallocarray (p, nfactors + 1, sizeof p[0]);
-      e = xireallocarray (e, nfactors + 1, sizeof e[0]);
+      if (factors->nfactors == factors->nalloc)
+        {
+          p = xpalloc (p, &factors->nalloc, 1, -1, sizeof *p);
+          e = xireallocarray (e, factors->nalloc, sizeof *e);
+        }
 
       mpz_init (p[nfactors]);
-      for (long j = nfactors - 1; j > i; j--)
+      for (ptrdiff_t j = nfactors - 1; j > i; j--)
         {
           mpz_set (p[j + 1], p[j]);
           e[j + 1] = e[j];
index 4c3c7b5905605a07dea38ec8e7373cf1bff7f520..c45f3b65af95db32b2c8d99e23fff846f9a28a69 100644 (file)
@@ -206,6 +206,7 @@ static uintmax_t max_n_unchanged_stats_between_opens =
    files, or perhaps other processes the user cares about).  */
 static int nbpids = 0;
 static pid_t * pids = nullptr;
+static idx_t pids_alloc;
 
 /* True if we have ever read standard input.  */
 static bool have_read_stdin;
@@ -2208,13 +2209,11 @@ parse_options (int argc, char **argv,
           break;
 
         case PID_OPTION:
-          {
-            pid_t pid =
-              xdectoumax (optarg, 0, PID_T_MAX, "", _("invalid PID"), 0);
-            pids = xreallocarray (pids, nbpids + 1, sizeof (pid_t));
-            pids[nbpids] = pid;
-            nbpids++;
-          }
+          if (nbpids == pids_alloc)
+            pids = xpalloc (pids, &pids_alloc, 1,
+                            MIN (INT_MAX, PTRDIFF_MAX), sizeof *pids);
+          pids[nbpids++] = xdectoumax (optarg, 0, PID_T_MAX, "",
+                                       _("invalid PID"), 0);
           break;
 
         case PRESUME_INPUT_PIPE_OPTION: