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
- Downscale the bitmap before copying so totalSize stays reasonable.
- Check Marshal.GetLastWin32Error() after the failure to confirm ERROR_NOT_ENOUGH_MEMORY (8).
- 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
- Downscale very large bitmaps before copying.
- Bound totalSize before allocating.
- Free other large allocations before clipboard copy.
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
- Failed to lock global memory
- Failed to set clipboard data
- Failed to decode bitmap
- Failed to open clipboard
- Failed to empty clipboard
AI-assisted analysis of SubtitleEdit/subtitleedit@17a9f07487 (2026-08-13).
Data as JSON: /api/errors/96db4c0965360f16.
Report an issue: GitHub.