SubtitleEdit/subtitleedit · error · InvalidOperationException

Failed to allocate global memory

Error message

Failed to allocate global memory

What it means

Thrown in CopyImageToClipboardWindows when GlobalAlloc(GMEM_MOVEABLE, totalSize) returns IntPtr.Zero — the Win32 allocator refused to grant a moveable global block large enough for the BITMAPINFOHEADER plus the BGRA pixel data. Zero from GlobalAlloc almost always means out-of-memory (the bitmap dimensions make totalSize huge) or, rarely, an invalid size.

Source

Thrown at src/ui/Logic/ClipboardHelper.cs:213

                // Ensure we have BGRA format
                using var bgraBitmap = new SkiaSharp.SKBitmap(width, height, SkiaSharp.SKColorType.Bgra8888, SkiaSharp.SKAlphaType.Premul);
                using var canvas = new SkiaSharp.SKCanvas(bgraBitmap);
                canvas.DrawBitmap(skBitmap, 0, 0);
                canvas.Flush();

                var pixels = bgraBitmap.Bytes;

                // Calculate sizes
                var stride = width * 4; // 4 bytes per pixel (BGRA)
                var imageSize = stride * height;
                var headerSize = Marshal.SizeOf<BITMAPINFOHEADER>();
                var totalSize = headerSize + imageSize;

                // Allocate global memory
                hGlobal = GlobalAlloc(GMEM_MOVEABLE, new UIntPtr((uint)totalSize));
                if (hGlobal == IntPtr.Zero)
                {
                    throw new InvalidOperationException("Failed to allocate global memory");
                }

                IntPtr ptr = GlobalLock(hGlobal);
                if (ptr == IntPtr.Zero)
                {
                    GlobalFree(hGlobal);
                    throw new InvalidOperationException("Failed to lock global memory");
                }

                try
                {
                    // Write BITMAPINFOHEADER
                    var header = new BITMAPINFOHEADER
                    {
                        biSize = (uint)headerSize,
                        biWidth = width,
                        biHeight = height, // positive for bottom-up DIB
                        biPlanes = 1,

View on GitHub (pinned to 17a9f07487)

Solutions

  1. Downscale the bitmap before copying so totalSize stays reasonable.
  2. Check Marshal.GetLastWin32Error() after the failure to confirm ERROR_NOT_ENOUGH_MEMORY (8).
  3. Free memory / close other large allocations before retrying the copy.

Example fix

// before
hGlobal = GlobalAlloc(GMEM_MOVEABLE, new UIntPtr((uint)totalSize));
if (hGlobal == IntPtr.Zero) throw new InvalidOperationException("Failed to allocate global memory");

// after - bound the size and surface the Win32 error
const long MaxClipboardBytes = 64 * 1024 * 1024;
if (totalSize > MaxClipboardBytes)
    throw new InvalidOperationException($"Image too large to copy ({totalSize} bytes).");
hGlobal = GlobalAlloc(GMEM_MOVEABLE, new UIntPtr((uint)totalSize));
if (hGlobal == IntPtr.Zero)
    throw new InvalidOperationException($"Failed to allocate global memory (Win32 error {Marshal.GetLastWin32Error()}).");
Defensive patterns

Strategy: validation

Validate before calling

const long MaxClipboardBytes = 64L * 1024 * 1024;
if (totalSize > MaxClipboardBytes) throw new InvalidOperationException($"Image too large ({totalSize} bytes).");

Try / catch

try { /* GlobalAlloc ... */ }
catch (InvalidOperationException ex) when (ex.Message == "Failed to allocate global memory")
{ SeLogger.Error($"GlobalAlloc failed (Win32 {Marshal.GetLastWin32Error()})"); throw; }

Prevention

When it happens

Trigger: A very large bitmap where stride*height (4 bytes/pixel) plus header overflows available memory or exceeds allocatable limits; totalSize overflowing to a bogus value; the process is already near its memory ceiling.

Common situations: Copying a multi-megapixel/high-DPI screenshot; running on a low-memory machine; a memory leak elsewhere pushing the process to its limit; extremely large image dimensions.

Related errors


AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13). Data as JSON: /api/errors/96db4c0965360f16. Report an issue: GitHub.