Commit 61596ce6 for tesseract
commit 61596ce668c9455bc3464f23c6456bbae7df868c
Author: Stefan Weil <sw@weilnetz.de>
Date: Thu Jun 18 17:57:03 2026 +0200
Modernize ScrollView memory management with smart pointers
Replace raw pointer allocations with std::unique_ptr for:
- Global static mutex pointers (svmap_mu, waiting_for_events_mu)
- Stream_ (SVNetwork)
- points_ (SVPolyLineBuffer)
- semaphore_ (SVSemaphore)
This eliminates manual memory management, potential memory leaks,
and provides RAII-based resource management.
Updated GetStream() to return a reference instead of pointer
for a cleaner API.
Assisted-by: minimax-m2.7 (MiniMax)
Signed-off-by: Stefan Weil <sw@weilnetz.de>
diff --git a/src/viewer/scrollview.cpp b/src/viewer/scrollview.cpp
index 4b4f6113..054880b5 100644
--- a/src/viewer/scrollview.cpp
+++ b/src/viewer/scrollview.cpp
@@ -53,11 +53,11 @@ struct SVPolyLineBuffer {
// A map between the window IDs and their corresponding pointers.
static std::map<int, ScrollView *> svmap;
-static std::mutex *svmap_mu;
+static std::unique_ptr<std::mutex> svmap_mu;
// A map of all semaphores waiting for a specific event on a specific window.
static std::map<std::pair<ScrollView *, SVEventType>,
std::pair<SVSemaphore *, std::unique_ptr<SVEvent>>> waiting_for_events;
-static std::mutex *waiting_for_events_mu;
+static std::unique_ptr<std::mutex> waiting_for_events_mu;
std::unique_ptr<SVEvent> SVEvent::copy() const {
auto any = std::unique_ptr<SVEvent>(new SVEvent);
@@ -89,7 +89,7 @@ void ScrollView::MessageReceiver() {
char *message = nullptr;
// Wait until a new message appears in the input stream_.
do {
- message = ScrollView::GetStream()->Receive();
+ message = ScrollView::GetStream().Receive();
} while (message == nullptr);
// This is the main loop which iterates until the server is dead (strlen =
@@ -177,7 +177,7 @@ void ScrollView::MessageReceiver() {
// Wait until a new message appears in the input stream_.
do {
- message = ScrollView::GetStream()->Receive();
+ message = ScrollView::GetStream().Receive();
} while (message == nullptr);
}
}
@@ -239,7 +239,7 @@ static const uint8_t table_colors[ScrollView::GREEN_YELLOW + 1][4] = {
* Scrollview implementation.
*******************************************************************************/
-SVNetwork *ScrollView::stream_ = nullptr;
+std::unique_ptr<SVNetwork> ScrollView::stream_;
int ScrollView::nr_created_windows_ = 0;
int ScrollView::image_index_ = 0;
@@ -272,9 +272,9 @@ void ScrollView::Initialize(const char *name, int x_pos, int y_pos, int x_size,
// network connection yet and we have to set it up in a different thread.
if (stream_ == nullptr) {
nr_created_windows_ = 0;
- stream_ = new SVNetwork(server_name, kSvPort);
- waiting_for_events_mu = new std::mutex();
- svmap_mu = new std::mutex();
+ stream_ = std::make_unique<SVNetwork>(server_name, kSvPort);
+ waiting_for_events_mu = std::make_unique<std::mutex>();
+ svmap_mu = std::make_unique<std::mutex>();
SendRawMessage("svmain = luajava.bindClass('com.google.scrollview.ScrollView')\n");
std::thread t(&ScrollView::MessageReceiver);
t.detach();
@@ -289,7 +289,7 @@ void ScrollView::Initialize(const char *name, int x_pos, int y_pos, int x_size,
window_name_ = name;
window_id_ = nr_created_windows_;
// Set up polygon buffering.
- points_ = new SVPolyLineBuffer;
+ points_ = std::make_unique<SVPolyLineBuffer>();
points_->empty = true;
svmap_mu->lock();
@@ -300,7 +300,7 @@ void ScrollView::Initialize(const char *name, int x_pos, int y_pos, int x_size,
i = nullptr;
}
- semaphore_ = new SVSemaphore();
+ semaphore_ = std::make_unique<SVSemaphore>();
// Set up an actual Window on the client side.
char message[kMaxMsgSize];
@@ -372,8 +372,6 @@ ScrollView::~ScrollView() {
} else {
svmap_mu->unlock();
}
- delete semaphore_;
- delete points_;
#endif // !GRAPHICS_DISABLED
}
diff --git a/src/viewer/scrollview.h b/src/viewer/scrollview.h
index 7e4f22e5..b2dc9b2f 100644
--- a/src/viewer/scrollview.h
+++ b/src/viewer/scrollview.h
@@ -378,8 +378,8 @@ private:
void Signal();
// Returns the unique, shared network stream.
- static SVNetwork *GetStream() {
- return stream_;
+ static SVNetwork &GetStream() {
+ return *stream_;
}
// Starts a new event handler.
@@ -396,7 +396,7 @@ private:
// The id of the window.
int window_id_;
// The points of the currently under-construction polyline.
- SVPolyLineBuffer *points_;
+ std::unique_ptr<SVPolyLineBuffer> points_;
// Whether the axis is reversed.
bool y_axis_is_reversed_;
// Set to true only after the event handler has terminated.
@@ -410,7 +410,7 @@ private:
static int image_index_;
// The stream through which the c++ client is connected to the server.
- static SVNetwork *stream_;
+ static std::unique_ptr<SVNetwork> stream_;
// Table of all the currently queued events.
std::unique_ptr<SVEvent> event_table_[SVET_COUNT];
@@ -419,7 +419,7 @@ private:
std::mutex mutex_;
// Semaphore to the thread belonging to this window.
- SVSemaphore *semaphore_;
+ std::unique_ptr<SVSemaphore> semaphore_;
#endif // !GRAPHICS_DISABLED
};