Yalantis/uCrop · error · CImgInstanceException

CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%

Error message

CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).

What it means

The CImg(size_x,size_y,size_z,size_c) constructor calls safe_size() then new T[siz]; if the allocation throws, the constructor resets the image to empty and rethrows as CImgInstanceException reporting the human-readable byte size and the requested dimensions. It means the system could not supply the memory for that image (bad_alloc from operator new).

Source

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

       \warning
       - The allocated pixel buffer is \e not filled with a default value, and is likely to contain garbage values.
         In order to initialize pixel values during construction (e.g. with \c 0), use constructor
         CImg(unsigned int,unsigned int,unsigned int,unsigned int,T) instead.
       \par Example
       \code
       CImg<float> img1(256,256,1,3); // Construct a 256x256x1x3 (color) image, filled with garbage values
       CImg<float> img2(256,256,1,3,0); // Construct a 256x256x1x3 (color) image, filled with value '0'
       \endcode
    **/
    explicit CImg(const unsigned int size_x, const unsigned int size_y=1,
                  const unsigned int size_z=1, const unsigned int size_c=1):
      _is_shared(false) {
      const size_t siz = safe_size(size_x,size_y,size_z,size_c);
      if (siz) {
        _width = size_x; _height = size_y; _depth = size_z; _spectrum = size_c;
        try { _data = new T[siz]; } catch (...) {
          _width = _height = _depth = _spectrum = 0; _data = 0;
          throw CImgInstanceException(_cimg_instance
                                      "CImg(): Failed to allocate memory (%s) for image (%u,%u,%u,%u).",
                                      cimg_instance,
                                      cimg::strbuffersize(sizeof(T)*size_x*size_y*size_z*size_c),
                                      size_x,size_y,size_z,size_c);
        }
      } else { _width = _height = _depth = _spectrum = 0; _data = 0; }
    }

    //! Construct image with specified size and initialize pixel values.
    /**
       \param size_x Image width().
       \param size_y Image height().
       \param size_z Image depth().
       \param size_c Image spectrum() (number of channels).
       \param value Initialization value.
       \note
       - Similar to CImg(unsigned int,unsigned int,unsigned int,unsigned int),
         but it also fills the pixel buffer with the specified \c value.

View on GitHub (pinned to f788b534b4)

Solutions

  1. Reduce the image dimensions or process in tiles/streams.
  2. Catch CImgInstanceException (or std::bad_alloc) and handle gracefully with a smaller buffer.
  3. Free memory / fix leaks; check the process memory limit (ulimit -v, container limits).
  4. Use a 64-bit build and a smaller pixel type (unsigned char instead of float/double).

Example fix

// before
CImg<float> vol(40000, 40000, 100); // ~640 GB -> throws
// after
try { CImg<float> vol(4000, 4000, 100); } // ~6.4 GB
catch (CImgInstanceException &e) { /* fall back to tiling */ }
Defensive patterns

Strategy: try-catch

Validate before calling

unsigned long long bytes = (unsigned long long)sizeof(T)*sx*sy*sz*sc;
if (bytes > AVAILABLE_BUDGET) return fail_oom(bytes);

Try / catch

try { CImg<T> img(sx,sy,sz,sc); }
catch (cimg_library::CImgInstanceException &e) { fprintf(stderr, "%s", e.what()); /* fall back to smaller size */ }

Prevention

When it happens

Trigger: new T[siz] throwing std::bad_alloc because requested bytes exceed available memory/swap or address space, for the value-initialized (fill(value)) constructor.

Common situations: Allocating very large images (gigapixel, large 3D volumes) on memory-constrained machines or 32-bit processes; memory fragmentation; container/VM memory limits; memory leaks elsewhere exhausting the heap.

Related errors


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