Chilkat C++ — Memory Leaks

A frequent question from C++ developers, and why the answer is reassuring — on every platform Chilkat supports.

The Chilkat C++ library is cross-platform. It runs on Windows (Visual C++, MinGW), Linux, macOS, iOS, Android, and Embarcadero C++ Builder. The behavior described below is the same everywhere; only the leak-detection tool differs by environment, and an example for each is given near the bottom of this page.
Question Does the Chilkat C++ library leak memory?
Answer No.

What is often mistaken for a memory leak is actually intentional memory caching used to improve performance.

Why memory stays allocated

Many Chilkat C++ classes initialize internal lookup tables, caches, or other shared data structures the first time they are needed. These allocations are made only once and are then reused by all subsequent Chilkat objects and method calls for the lifetime of the process. This avoids repeatedly allocating and freeing the same resources, improving both performance and scalability.

Because these shared structures intentionally remain allocated until the application exits, Visual C++'s _CrtDumpMemoryLeaks() may report them as memory leaks if it is called before the Chilkat library performs its final cleanup. These are not true memory leaks — the memory is still owned by the library and would normally be reclaimed automatically when the process terminates.

Verifying your application has no leaks

The procedure is identical on every platform. If you want to confirm that your application has no memory leaks, call CkSettings::cleanupMemory() immediately before your program exits. This releases all internally cached resources so that whatever leak detector you use — the Visual C++ CRT debug heap, Valgrind, AddressSanitizer, the macOS leaks tool, CodeGuard, and so on — reports only genuine leaks.

The one constant across all environments is CkSettings::cleanupMemory(). Only the leak-detection tool changes from platform to platform.

Important — how to call cleanupMemory()
  • CkSettings::cleanupMemory() should be called only once, immediately before the application terminates.
  • After calling cleanupMemory(), no other Chilkat methods may be called — including the destructors of any remaining Chilkat objects. Ensure all Chilkat objects have already gone out of scope or been destroyed before calling it.

Demonstrating that memory is stable

A good way to demonstrate that the library does not leak memory is to execute the same Chilkat operation repeatedly — for example, 100,000 times in a loop. Memory usage will initially increase as the shared internal structures are created, but it will then remain essentially constant, because those structures are reused rather than allocated again.

The universal pattern

Regardless of platform or compiler, the only Chilkat-specific requirement is to call CkSettings::cleanupMemory() as the final Chilkat call before your program exits, after every Chilkat object has been destroyed:

#include "CkSettings.h"
#include "CkXml.h"

void TestLoadXml()
{
    CkXml xml;
    xml.LoadXmlFile("crisp.xml");
    xml.SaveXml("out.xml");
}                       // 'xml' is destroyed here, before cleanupMemory().

int main()
{
    TestLoadXml();

    // Must be the final Chilkat call the program makes.
    CkSettings::cleanupMemory();

    return 0;
}

The C++ above does not change between environments. Only the build flags, the run command, and the leak detector differ, as shown next.

Leak detection by environment

Windows Visual C++ (MSVC)

Use the Visual C++ CRT debug heap. Build in the Debug configuration and call _CrtDumpMemoryLeaks() after cleanupMemory():

#define _CRTDBG_MAP_ALLOC
#include "stdafx.h"
#include <stdio.h>
#include <crtdbg.h>

#include "CkSettings.h"
#include "CkXml.h"

void TestLoadXml()
{
    CkXml xml;
    xml.LoadXmlFile("crisp.xml");
    xml.SaveXml("out.xml");
}

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine,
                     int nCmdShow)
{
    TestLoadXml();

    // This must be the final Chilkat call made by the application.
    CkSettings::cleanupMemory();

    // Reports any remaining (genuine) allocations.
    _CrtDumpMemoryLeaks();

    return 0;
}
Windows MinGW / MSYS2 (GCC or Clang)

_CrtDumpMemoryLeaks() belongs to the MSVC debug runtime and is not available with MinGW. Use AddressSanitizer (which includes LeakSanitizer) instead, or a tool such as Dr. Memory. With the universal main() shown above:

Build & run
g++ -g -fsanitize=address main.cpp -lchilkat -o app
./app   # LeakSanitizer prints any real leaks at exit
Linux GCC or Clang

Two good options — choose either:

Option A — Valgrind (no special build flags)
g++ -g main.cpp -lchilkat -o app
valgrind --leak-check=full --show-leak-kinds=all ./app
Option B — AddressSanitizer / LeakSanitizer
g++ -g -fsanitize=address main.cpp -lchilkat -o app
./app
macOS Clang / Xcode

Use Apple's built-in leaks tool (or the Leaks instrument in Xcode Instruments):

Build & run
clang++ -g main.cpp -lchilkat -o app
MallocStackLogging=1 leaks --atExit -- ./app

On modern macOS, Valgrind has little or no support (especially on Apple Silicon), and LeakSanitizer is unreliable on Apple Silicon, so the leaks tool or Instruments is recommended. Do not combine leaks with -fsanitize=address.

iOS Xcode

Apps don't exit the way command-line programs do, so leak checking is usually done in a test harness. Use the Leaks instrument in Xcode Instruments, or enable Address Sanitizer / Malloc Stack Logging in your scheme's Diagnostics tab. Call CkSettings::cleanupMemory() at the end of your test run (after all Chilkat objects are gone) before measuring.

Android NDK (Clang)

Build your native library with the NDK's AddressSanitizer (which includes LeakSanitizer), or use malloc_debug. Add the sanitizer flag to your native build and call CkSettings::cleanupMemory() before your native code finishes:

CMake (CMakeLists.txt)
target_compile_options(yourlib PRIVATE -fsanitize=address -g)
target_link_options(yourlib PRIVATE -fsanitize=address)
Cross-platform Embarcadero C++ Builder

Enable CodeGuard (the built-in runtime memory checker) in Project → Options → C++ Compiler → CodeGuard, then call CkSettings::cleanupMemory() before the program exits so CodeGuard reports only genuine leaks.