nlib
heap/nmalloc_leakcheck/nmalloc_leakcheck.cpp

A sample that checks for memory leaks using the nmalloc_query(NMALLOC_QUERY_HEAP_HASH, ...) function. For a more advanced technique, see the object_tracking sample.

/*---------------------------------------------------------------------------*
Project: CrossRoad
Copyright (C)2012-2016 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
*---------------------------------------------------------------------------*/
#include <string.h>
static char* MyStrDup(const char* str) {
if (!str) return NULL;
size_t len = strlen(str);
char* ptr = reinterpret_cast<char*>(nmalloc(len + 1));
if (!ptr) return NULL;
nlib_strcpy(ptr, len + 1, str);
return ptr;
}
// Disables caching by CachedHeap here.
// Otherwise, cached memory is marked as allocated.
#ifdef NLIB_HAS_VIRTUALMEMORY
extern "C" void nmalloc_get_settings(NMallocSettings* settings) {
settings->addr = NULL;
settings->size = 1024 * 128;
}
#else
const size_t heapmem_size = 1024 * 128;
NLIB_ALIGNAS(4096) static char heapmem[heapmem_size];
extern "C" void nmalloc_get_settings(NMallocSettings* settings) {
settings->addr = heapmem;
settings->size = heapmem_size;
}
#endif
static void Advance(char* s) {
if (!s) return;
nlib_printf("Before Advance: %s\n", s);
char* p = s;
while (*p) {
++(*p);
++p;
}
nlib_printf("After Advance: %s\n", s);
}
static bool SampleMain(int, char**) {
HeapHash before, after;
// Summarizes the current central heap status.
nmalloc_query(NMALLOC_QUERY_HEAP_HASH, &before);
// MyStrDup() copies "ABC" to the newly allocated memory internally.
// But Advance() does not free the memory.
Advance(MyStrDup("ABC"));
// There is a memory leak here.
// Summarizes the current central heap status.
nmalloc_query(NMALLOC_QUERY_HEAP_HASH, &after);
if (before != after) {
nlib_printf("\n!!! leak detected !!!\n");
nlib_printf(" alloc_count: before %" PRIuS ", after %" PRIuS "\n", before.alloc_count,
after.alloc_count);
nlib_printf(" alloc_size: before %" PRIuS ", after %" PRIuS "\n", before.alloc_size,
after.alloc_size);
nlib_printf(" hash: before %" PRIuS ", after %" PRIuS "\n", before.hash, after.hash);
}
return true;
}
NLIB_MAINFUNC