{"record":{"id":"96db4c0965360f16","repo":"SubtitleEdit/subtitleedit","slug":"failed-to-allocate-global-memory","errorCode":null,"errorMessage":"Failed to allocate global memory","messagePattern":"Failed to allocate global memory","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/ui/Logic/ClipboardHelper.cs","lineNumber":213,"sourceCode":"                // Ensure we have BGRA format\n                using var bgraBitmap = new SkiaSharp.SKBitmap(width, height, SkiaSharp.SKColorType.Bgra8888, SkiaSharp.SKAlphaType.Premul);\n                using var canvas = new SkiaSharp.SKCanvas(bgraBitmap);\n                canvas.DrawBitmap(skBitmap, 0, 0);\n                canvas.Flush();\n\n                var pixels = bgraBitmap.Bytes;\n\n                // Calculate sizes\n                var stride = width * 4; // 4 bytes per pixel (BGRA)\n                var imageSize = stride * height;\n                var headerSize = Marshal.SizeOf<BITMAPINFOHEADER>();\n                var totalSize = headerSize + imageSize;\n\n                // Allocate global memory\n                hGlobal = GlobalAlloc(GMEM_MOVEABLE, new UIntPtr((uint)totalSize));\n                if (hGlobal == IntPtr.Zero)\n                {\n                    throw new InvalidOperationException(\"Failed to allocate global memory\");\n                }\n\n                IntPtr ptr = GlobalLock(hGlobal);\n                if (ptr == IntPtr.Zero)\n                {\n                    GlobalFree(hGlobal);\n                    throw new InvalidOperationException(\"Failed to lock global memory\");\n                }\n\n                try\n                {\n                    // Write BITMAPINFOHEADER\n                    var header = new BITMAPINFOHEADER\n                    {\n                        biSize = (uint)headerSize,\n                        biWidth = width,\n                        biHeight = height, // positive for bottom-up DIB\n                        biPlanes = 1,","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/SubtitleEdit/subtitleedit/blob/17a9f0748781032255db3526b7215d2fb891e3af/src/ui/Logic/ClipboardHelper.cs#L195-L231","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nhGlobal = GlobalAlloc(GMEM_MOVEABLE, new UIntPtr((uint)totalSize));\nif (hGlobal == IntPtr.Zero) throw new InvalidOperationException(\"Failed to allocate global memory\");\n\n// after - bound the size and surface the Win32 error\nconst long MaxClipboardBytes = 64 * 1024 * 1024;\nif (totalSize > MaxClipboardBytes)\n    throw new InvalidOperationException($\"Image too large to copy ({totalSize} bytes).\");\nhGlobal = GlobalAlloc(GMEM_MOVEABLE, new UIntPtr((uint)totalSize));\nif (hGlobal == IntPtr.Zero)\n    throw new InvalidOperationException($\"Failed to allocate global memory (Win32 error {Marshal.GetLastWin32Error()}).\");","handlingStrategy":"validation","validationCode":"const long MaxClipboardBytes = 64L * 1024 * 1024;\nif (totalSize > MaxClipboardBytes) throw new InvalidOperationException($\"Image too large ({totalSize} bytes).\");","typeGuard":null,"tryCatchPattern":"try { /* GlobalAlloc ... */ }\ncatch (InvalidOperationException ex) when (ex.Message == \"Failed to allocate global memory\")\n{ SeLogger.Error($\"GlobalAlloc failed (Win32 {Marshal.GetLastWin32Error()})\"); throw; }","preventionTips":["Downscale very large bitmaps before copying.","Bound totalSize before allocating.","Free other large allocations before clipboard copy."],"tags":["clipboard","windows","win32","memory","image"],"backgroundTag":null,"analyzedSha":"17a9f0748781032255db3526b7215d2fb891e3af","analyzedAt":"2026-08-13T18:11:43.374Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}