Yalantis/uCrop · error · CImgArgumentException

[" cimg_appname "_math_parser] CImg<

Error message

[" cimg_appname "_math_parser] CImg<%s>: Function '%s()': Specified dynamic array #%u contains no elements.

What it means

When a dynamic-array image passes the shape check but its stored element counter siz is 0, popping/removing an element is impossible, so the parser throws this error. It indicates the dynamic array is empty at the time of the operation.

Solutions

  1. Check siz > 0 before popping, e.g. guard the expression with a size test.
  2. Balance da_push and da_pop calls in your loop logic.
  3. Re-initialize the array with da_init when starting a fresh algorithm pass.
  4. Track element counts in host code to avoid draining the array.

Example fix

// before
img.fill("da_pop(0)"); // may be empty
// after
img.fill("siz>0?da_pop(0):nan");
Defensive patterns

Strategy: validation

Validate before calling

double siz = arr ? arr(0, arr.height()-1) : 0;
if (siz <= 0) throw std::runtime_error("dynamic array is empty");

Type guard

bool dynArrayNonEmpty(const CImg<T>& a) { return !a.is_empty() && a(0,a.height()-1) > 0; }

Try / catch

try { img.fill(popExpr); } catch (const cimg_library::CImgArgumentException& e) { /* array drained; stop popping */ }

Prevention

When it happens

Trigger: Calling a pop/heap-removal MP opcode (e.g. 'da_pop(...)' or min-heap removal) on an array initialized with zero elements, or popping more times than elements were pushed.

Common situations: Unbalanced push/pop sequences in expression loops; reusing an array image already drained by earlier expressions; logic errors in heap-based algorithms (e.g. dijkstra) draining the queue.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/322067ae127920aa. Report an issue: GitHub.

Appendix: source

Thrown at ucrop/src/main/jni/CImg.h:26269

      static double mp_da_back_or_pop(_cimg_math_parser& mp) {
        const bool is_pop_heap = mp.opcode[4]==2, is_pop = (bool)mp.opcode[4];
        const char *const s_op = is_pop_heap?"da_pop_heap":is_pop?"da_pop":"da_back";
        mp_check_list(mp,s_op);
        const unsigned int
          dim = (unsigned int)mp.opcode[2],
          ind = (unsigned int)cimg::mod((int)_mp_arg(3),mp.imglist.width());
        double *const ptrd = &_mp_arg(1) + (dim>1?1:0);
        CImg<T> &img = mp.imglist[ind];
        int siz = img?(int)cimg::float2uint((float)img[img._height - 1]):0;
        if (img && (img._width!=1 || img._depth!=1 || siz<0 || siz>img.height() - 1))
          throw CImgArgumentException("[" cimg_appname "_math_parser] CImg<%s>: Function '%s()': "
                                      "Specified image #%u of size (%d,%d,%d,%d) cannot be used as dynamic array%s.",
                                      mp.imgout.pixel_type(),s_op,ind,
                                      img.width(),img.height(),img.depth(),img.spectrum(),
                                      img._width==1 && img._depth==1?"":" (contains invalid element counter)");
        if (!siz)
          throw CImgArgumentException("[" cimg_appname "_math_parser] CImg<%s>: Function '%s()': "
                                      "Specified dynamic array #%u contains no elements.",
                                      mp.imgout.pixel_type(),s_op,ind);
        const int siz1 = siz - 1;
        if (is_pop_heap) { // Heapify-down
          if (dim==1) cimg::swap(img[0],img[siz1]);
          else {
            T *ptr0 = img.data(), *ptr1 = img.data(0,siz1);
            cimg_forC(img,c) { cimg::swap(*ptr0,*ptr1); ptr0+=img._height; ptr1+=img._height; }
          }
          int index = 0;
          while (true) {
            const int child_left = 2*index + 1, child_right = child_left + 1;
            int smallest = index;
            if (child_left<siz1 && img[child_left]<img[smallest]) smallest = child_left;
            if (child_right<siz1 && img[child_right]<img[smallest]) smallest = child_right;
            if (smallest!=index) {
              if (dim==1) cimg::swap(img[index],img[smallest]);
              else {

View on GitHub (pinned to f788b534b4)