From 9b5c8368daa97a5b58a378d9c4eab66ebb018cb0 Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sat, 28 Dec 2024 21:49:02 +0530 Subject: Fix memory leak issue with c++ interop --- TODO.norg | 2 +- cpp/libchelleport.cpp | 2 +- flake.nix | 1 + src/Chelleport/OCR.hs | 7 ++++--- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/TODO.norg b/TODO.norg index d71d249..2228e2d 100644 --- a/TODO.norg +++ b/TODO.norg @@ -1,11 +1,11 @@ * Current + - ( ) Investigate memory leak with c++ ffi when re-evaluating ocr - ( ) TextStyle for drawText - ( ) Middle click - (-) Optimize speed of ocr - ( ) Backspace deletes a single character in search mode * Later - - ( ) Separate state for hint modes into ModeHint constructor - ( ) Look into making mouse controls (click/mouse down/mouse up) cross-platform - ( ) Look into making screenshot cross-platform - ( ) Lens-ey setup for Mode access diff --git a/cpp/libchelleport.cpp b/cpp/libchelleport.cpp index 53ba64e..010fdd4 100644 --- a/cpp/libchelleport.cpp +++ b/cpp/libchelleport.cpp @@ -13,7 +13,7 @@ extern "C" OCRMatch *findWordCoordinates(const char *image_path, int *size) { OCRMatchSet matches; MEASURE("OCR", { matches = extractTextMatches(image_path); }); - static OCRMatch *ptr = new OCRMatch[matches.size()]; + OCRMatch *ptr = new OCRMatch[matches.size()]; std::copy(matches.begin(), matches.end(), ptr); *size = matches.size(); diff --git a/flake.nix b/flake.nix index 3486cff..93f0551 100644 --- a/flake.nix +++ b/flake.nix @@ -47,6 +47,7 @@ just nodemon clang-tools + valgrind ]; in { haskellProjects.default = { diff --git a/src/Chelleport/OCR.hs b/src/Chelleport/OCR.hs index 64c69e5..43ab34d 100644 --- a/src/Chelleport/OCR.hs +++ b/src/Chelleport/OCR.hs @@ -5,7 +5,7 @@ import Control.Concurrent (threadDelay) import Control.Monad.IO.Class (MonadIO (liftIO)) import Control.Monad.RWS (MonadReader (ask)) import qualified Data.ByteString as BS -import Foreign (Bits (shiftR), Ptr, Storable (peek, pokeByteOff), alloca, allocaBytes, peekArray, (.&.)) +import Foreign (Bits (shiftR), Ptr, Storable (peek, pokeByteOff), alloca, allocaBytes, free, peekArray, (.&.)) import Foreign.C (CInt, CString, newCString) import GHC.IO.Handle.FD (withFile) import GHC.IO.IOMode (IOMode (WriteMode)) @@ -31,7 +31,6 @@ instance (MonadIO m) => MonadOCR (AppM m) where pure path getWordsInImage filePath = liftIO $ do - -- result `seq` pure result -- Strict eval findWordCoordinates filePath <* removeFile filePath findWordCoordinates :: String -> IO [OCRMatch] @@ -40,7 +39,9 @@ findWordCoordinates imgPath = alloca $ \sizePtr -> do arrayPtr <- c_getAllWordCoordinates imgPathC sizePtr size <- peek sizePtr - peekArray (fromIntegral size) arrayPtr + result <- peekArray (fromIntegral size) arrayPtr + free arrayPtr + pure result createTemporaryScreenshot :: DrawContext -> (CInt, CInt) -> (CInt, CInt) -> IO String createTemporaryScreenshot ctx offset size = do -- cgit v1.3.1