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.

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.

Appendix: 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)