I've got a problem with memory in C++ program with FLTK.
In this first case:
#include <Fl/Fl.H>
#include <Fl/Fl_Window.H>
enum {
win_w = 640,
win_h = 480,
btn_w = 80,
btn_h = 30
};
int main()
{
Fl_Window *window = new Fl_Window(win_w, win_h, "Hello, World!");
window->end();
window->show();
return Fl::run();
}
valgrind said that:
HEAP SUMMARY:
==2746== in use at exit: 711,091 bytes in 846 blocks
==2746== total heap usage: 13,330 allocs, 12,484 frees, 2,751,634 bytes allocated
==2746==
==2746== LEAK SUMMARY:
==2746== definitely lost: 0 bytes in 0 blocks
==2746== indirectly lost: 0 bytes in 0 blocks
==2746== possibly lost: 0 bytes in 0 blocks
==2746== still reachable: 711,091 bytes in 846 blocks
==2746== suppressed: 0 bytes in 0 blocks
==2746== Rerun with --leak-check=full to see details of leaked memory
If I will add a Fl_Button to this programm, we gonna have much more memory leaking.
...
Fl_Window *window = new Fl_Window(win_w, win_h, "Hello, World!");
Fl_Button *btn = new Fl_Button(win_w / 2 - btn_w / 2, win_h / 2 - btn_h / 2, btn_w, btn_h, "Button!");
window->end();
...
==2791== HEAP SUMMARY:
==2791== in use at exit: 1,065,964 bytes in 6,005 blocks
==2791== total heap usage: 25,233 allocs, 19,228 frees, 6,637,915 bytes allocated
==2791==
==2791== LEAK SUMMARY:
==2791== definitely lost: 5,376 bytes in 19 blocks
==2791== indirectly lost: 3,371 bytes in 128 blocks
==2791== possibly lost: 0 bytes in 0 blocks
==2791== still reachable: 1,057,217 bytes in 5,858 blocks
==2791== suppressed: 0 bytes in 0 blocks
==2791== Rerun with --leak-check=full to see details of leaked memory
On the one hand, this is normal, because we do not free memory. On the other hand, this can be said to be a classic example of a FLTK program. Are memory leaks normal in FLTK? And if it's OK, why shouldn't this lead to problems if the program has been running continuously for a very long time?
As mentioned by #drescherjrn, you can delete window after run. Something like
int main()
{
Fl_Window *window = new Fl_Window(win_w, win_h, "Hello, World!");
window->end();
window->show();
int rv = Fl::run();
delete window;
return rv;
}
Alternatively, C++ has a mechanism for this: auto_ptr (http://www.cplusplus.com/reference/memory/auto_ptr/auto_ptr/)
#include <memory>
int main()
{
std::auto_ptr<Fl_Window> window(new Fl_Window(win_w, win_h, "Hello, World!"));
window->end();
window->show();
return Fl::run();
}
You can try:
int main()
{
Fl_Window *window = new Fl_Window(win_w, win_h, "Hello, World!");
window->end();
window->show();
int retval = 1;
if (Fl::run())
retval =0;
delete window ;
return retval ;
}
Related
I am working on emulating rpm -qa using my own code that uses the librpm library. I am doing this as initial experimentation for a larger program that will analyze installed software for security purposes.
For now, I only open the RPM DB and close it without reading anything.
When I compare the output of valgrind for my code and against the valgrind output for rpm -qa, here are the results:
$ valgrind ./leaky
==8201== Memcheck, a memory error detector
==8201== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8201== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==8201== Command: ./leaky
==8201==
==8201==
==8201== HEAP SUMMARY:
==8201== in use at exit: 104,700 bytes in 2,352 blocks
==8201== total heap usage: 10,430 allocs, 8,078 frees, 2,292,650 bytes allocated
==8201==
==8201== LEAK SUMMARY:
==8201== definitely lost: 0 bytes in 0 blocks
==8201== indirectly lost: 0 bytes in 0 blocks
==8201== possibly lost: 25,740 bytes in 325 blocks
==8201== still reachable: 78,960 bytes in 2,027 blocks
==8201== suppressed: 0 bytes in 0 blocks
==8201== Rerun with --leak-check=full to see details of leaked memory
==8201==
==8201== For lists of detected and suppressed errors, rerun with: -s
==8201== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ valgrind rpm -qa > /dev/null
==8101== Memcheck, a memory error detector
==8101== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==8101== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==8101== Command: rpm -qa
==8101==
==8101==
==8101== HEAP SUMMARY:
==8101== in use at exit: 287 bytes in 2 blocks
==8101== total heap usage: 170,103 allocs, 170,101 frees, 120,309,981 bytes allocated
==8101==
==8101== LEAK SUMMARY:
==8101== definitely lost: 0 bytes in 0 blocks
==8101== indirectly lost: 0 bytes in 0 blocks
==8101== possibly lost: 0 bytes in 0 blocks
==8101== still reachable: 287 bytes in 2 blocks
==8101== suppressed: 0 bytes in 0 blocks
==8101== Rerun with --leak-check=full to see details of leaked memory
==8101==
==8101== For lists of detected and suppressed errors, rerun with: -s
==8101== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
As you can see, my program possibly lost 25,740 bytes, whereas rpm -qa lost 0 bytes.
Here is my code:
#include <rpm/rpmdb.h>
#include <rpm/rpmlib.h>
#include <rpm/rpmts.h>
bool openDb(rpmts & ts, rpmdbMatchIterator & mi);
void closeDb(rpmts & ts, rpmdbMatchIterator & mi);
int main()
{
rpmts ts;
rpmdbMatchIterator mi;
if (!openDb(ts, mi)) {
return 1;
}
closeDb(ts, mi);
return 0;
}
bool openDb(rpmts & ts, rpmdbMatchIterator & mi)
{
{
static volatile bool s_bHereBefore = false;
if (!s_bHereBefore) {
s_bHereBefore = true;
rpmReadConfigFiles(NULL, NULL);
}
}
mi = NULL;
ts = rpmtsCreate();
if (!ts) {
printf("RPM open failed\n");
} else {
mi = rpmtsInitIterator(ts, (rpmTag)RPMDBI_PACKAGES, NULL, 0);
if (!mi) {
printf("RPM iterator failed\n");
rpmtsFree(ts);
}
}
return mi != NULL;
}
void closeDb(rpmts & ts, rpmdbMatchIterator & mi)
{
mi = rpmdbFreeIterator(mi);
if (ts) {
rpmtsFree(ts);
}
}
I compile with g++ -Wall -Wextra -Wunused -Og -g try_to_fix_mem_leak.cpp -lrpm -o leaky.
I closely inspected my program, but I was unable to spot any memory leaks from manual inspection.
When I run valgrind --leak-check=full ./leaky and search the output for try_to_fix_mem_leak.cpp, all of the hits are for line 27, i.e., the rpmReadConfigFiles(NULL, NULL); line (technically there are also hits for line 13, but that is just because that is where the openDb call is made in main). (See pastebin link below.) But I don't know how this line could cause any memory leaks. The function's documentation for my version of librpm (4.16.1) doesn't mention anything about needing to free any memory.
How can I correctly open and close the RPM DB without leaking memory? Or, to put my question another way, how can I open and close the RPM DB while leaking at worst only as many bytes as rpm -qa does?
Edit
pastebin link with full output of valgrind --leak-check=full ./leaky.
A colleague of mine found that, in the code for the rpm binary itself, the RPM devs call the following two functions to free their memory:
rpmFreeMacros(NULL);
rpmFreeRpmrc();
To use rpmFreeMacros(), include the rpm/rpmmacro.h system header in your source code, and link against librpmio.so.
Here is my updated code:
#include <rpm/rpmdb.h>
#include <rpm/rpmlib.h>
#include <rpm/rpmts.h>
#include <rpm/rpmmacro.h>
bool openDb(rpmts & ts, rpmdbMatchIterator & mi);
void closeDb(rpmts & ts, rpmdbMatchIterator & mi);
int main()
{
rpmts ts;
rpmdbMatchIterator mi;
if (!openDb(ts, mi)) {
return 1;
}
closeDb(ts, mi);
return 0;
}
bool openDb(rpmts & ts, rpmdbMatchIterator & mi)
{
{
static volatile bool s_bHereBefore = false;
if (!s_bHereBefore) {
s_bHereBefore = true;
rpmReadConfigFiles(NULL, NULL);
}
}
mi = NULL;
ts = rpmtsCreate();
if (!ts) {
printf("RPM open failed\n");
} else {
mi = rpmtsInitIterator(ts, (rpmTag)RPMDBI_PACKAGES, NULL, 0);
if (!mi) {
printf("RPM iterator failed\n");
rpmtsFree(ts);
}
}
return mi != NULL;
}
void closeDb(rpmts & ts, rpmdbMatchIterator & mi)
{
mi = rpmdbFreeIterator(mi);
if (ts) {
rpmtsFree(ts);
}
rpmFreeMacros(NULL);
rpmFreeRpmrc();
}
Here is a diff between my new code (leak_fixed.cpp) and my old leaky code (try_to_fix_mem_leak.cpp):
$ diff -u try_to_fix_mem_leak.cpp leak_fixed.cpp
--- try_to_fix_mem_leak.cpp 2023-01-04 10:19:28.084587731 -0500
+++ leak_fixed.cpp 2023-01-04 10:19:57.484483431 -0500
## -1,6 +1,7 ##
#include <rpm/rpmdb.h>
#include <rpm/rpmlib.h>
#include <rpm/rpmts.h>
+#include <rpm/rpmmacro.h>
bool openDb(rpmts & ts, rpmdbMatchIterator & mi);
void closeDb(rpmts & ts, rpmdbMatchIterator & mi);
## -50,4 +51,6 ##
if (ts) {
rpmtsFree(ts);
}
+ rpmFreeMacros(NULL);
+ rpmFreeRpmrc();
}
I compile with g++ -Wall -Wextra -Wunused -Og -g leak_fixed.cpp -lrpm -lrpmio -o rpm_open_close. Note that I needed to add -lrpmio in order to be able to use the rpmFreeMacros() function.
I get the same leak summary output from valgrind for both my binary and for the system rpm binary:
$ valgrind ./rpm_open_close
==3470== Memcheck, a memory error detector
==3470== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3470== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==3470== Command: ./rpm_open_close
==3470==
==3470==
==3470== HEAP SUMMARY:
==3470== in use at exit: 287 bytes in 2 blocks
==3470== total heap usage: 10,495 allocs, 10,493 frees, 2,317,132 bytes allocated
==3470==
==3470== LEAK SUMMARY:
==3470== definitely lost: 0 bytes in 0 blocks
==3470== indirectly lost: 0 bytes in 0 blocks
==3470== possibly lost: 0 bytes in 0 blocks
==3470== still reachable: 287 bytes in 2 blocks
==3470== suppressed: 0 bytes in 0 blocks
==3470== Rerun with --leak-check=full to see details of leaked memory
==3470==
==3470== For lists of detected and suppressed errors, rerun with: -s
==3470== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ valgrind rpm -qa > /dev/null
==3483== Memcheck, a memory error detector
==3483== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3483== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==3483== Command: rpm -qa
==3483==
==3483==
==3483== HEAP SUMMARY:
==3483== in use at exit: 287 bytes in 2 blocks
==3483== total heap usage: 172,604 allocs, 172,602 frees, 121,827,169 bytes allocated
==3483==
==3483== LEAK SUMMARY:
==3483== definitely lost: 0 bytes in 0 blocks
==3483== indirectly lost: 0 bytes in 0 blocks
==3483== possibly lost: 0 bytes in 0 blocks
==3483== still reachable: 287 bytes in 2 blocks
==3483== suppressed: 0 bytes in 0 blocks
==3483== Rerun with --leak-check=full to see details of leaked memory
==3483==
==3483== For lists of detected and suppressed errors, rerun with: -s
==3483== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I´m running a big code with lots of MYSQL database access that and I´m noticing a memory leak that consumes the whole server memory after one day running.
By isolating pieces I end up with the following test code:
#include <iostream>
#include <string>
#include <sstream>
#include <thread>
#include <chrono>
#include "mysql_connection.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
int main() {
try
{
sql::Driver *driver = NULL;
sql::Connection *connection = NULL;
driver = get_driver_instance();
connection = driver->connect("tcp://127.0.0.1:3306", "user", "pass");
connection->setSchema("myschema");
connection->setAutoCommit(true);
while (true)
{
std::string sql("INSERT INTO tablename ('field1', 'field2', 'field3') VALUES ('1', '2', '3')");
sql::Statement *stmt;
stmt = connection->createStatement();
stmt->execute(sql.c_str());
stmt->close();
std::cout << sql << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
catch (std::exception& ex)
{
std::cout << "Error occurred: " << std::endl;
std::cout << ex.what() << std::endl;
}
catch(...)
{
std::cout << "Unknown failure occurred." << std::endl;
}
}
As the main while runs, the process memory usage starts increasing like 1Mb per minute.
Using valgrid --leak-check=full I got the following result after hitting to exit from the main loop:
==11988== Process terminating with default action of signal 2 (SIGINT)
==11988== at 0x57F5D6D: recv (recv.c:29)
==11988== by 0x5B1B022: vio_read (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.1.0)
==11988== by 0x5B1B0A4: vio_read_buff (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.1.0)
==11988== by 0x5AFA702: ??? (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.1.0)
==11988== by 0x5AFA976: ??? (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.1.0)
==11988== by 0x5AFB6A3: my_net_read (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.1.0)
==11988== by 0x5AF151C: cli_safe_read (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.1.0)
==11988== by 0x5AF2A15: ??? (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.1.0)
==11988== by 0x5AF43A5: mysql_real_query (in /usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.1.0)
==11988== by 0x4F15BEE: sql::mysql::NativeAPI::LibmysqlStaticProxy::real_query(st_mysql*, char const*, unsigned long) (in /usr/lib/libmysqlcppconn.so.7.1.1.3)
==11988== by 0x4F176F5: sql::mysql::NativeAPI::MySQL_NativeConnectionWrapper::query(sql::SQLString const&) (in /usr/lib/libmysqlcppconn.so.7.1.1.3)
==11988== by 0x4F10579: sql::mysql::MySQL_Statement::do_query(sql::SQLString const&) (in /usr/lib/libmysqlcppconn.so.7.1.1.3)
==11988==
==11988== HEAP SUMMARY:
==11988== in use at exit: 333,479 bytes in 1,869 blocks
==11988== total heap usage: 5,566 allocs, 3,697 frees, 1,100,674 bytes allocated
==11988==
==11988== 144,880 bytes in 1,811 blocks are definitely lost in loss record 42 of 42
==11988== at 0x4C2C12F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11988== by 0x4EC4334: sql::mysql::MySQL_Connection::createStatement() (in /usr/lib/libmysqlcppconn.so.7.1.1.3)
==11988== by 0x4011B7: main (test.cpp:32)
==11988==
==11988== LEAK SUMMARY:
==11988== definitely lost: 144,880 bytes in 1,811 blocks
==11988== indirectly lost: 0 bytes in 0 blocks
==11988== possibly lost: 0 bytes in 0 blocks
==11988== still reachable: 188,599 bytes in 58 blocks
==11988== suppressed: 0 bytes in 0 blocks
==11988== Reachable blocks (those to which a pointer was found) are not shown.
==11988== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==11988==
==11988== For counts of detected and suppressed errors, rerun with: -v
==11988== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
So, am I doing something wrong or is this a know MYSQL bug ? How to fix the code and/or mySQL ?
I´m running MySql 5.6.27-0ubuntu1 running on Ubuntu 15.10.
You're missing delete stmt. Better would be to use a std::unique_ptr<sql::Statement>.
(See e.g. https://dev.mysql.com/doc/connector-cpp/en/connector-cpp-examples-query.html)
Try
std::unique_ptr<sql::Statement> stmt(connection->CreateStatement());
I am trying to use DrMemory as it seems to be an easy to use Windows Memory Leaking detection tool: http://www.drmemory.org/
I purposely created the c++ app below that might have a memory leak.
#include <iostream>
using namespace std;
class Dog{
public:
int a;
string b;
Dog()
{
a = 1;
b = "alfred";
}
~Dog()
{
}
};
class Example{
public:
Dog* d1;
Dog* d2;
string a;
int b;
Example()
{
a = "test";
b = 15;
d1 = new Dog();
d2 = new Dog();
}
~Example()
{
//delete d;
}
};
void createObjects(){
for(unsigned int i=0; i < 200; i++)
{
Dog* d = new Dog();
Example* b = new Example();
}
Dog* d = new Dog();
d = NULL;
Example* b = new Example();
b = NULL;
}
int main()
{
createObjects();
return 0;
}
After building this app along with the following options (as instructed by DrMemory documentation) "-ggdb -static-libgcc -static-libstdc++" , I executed the executable with drmemory.exe, like this:
drmemory.exe TestingDrMemory.exe
However, I am not seeing any error/log message related to the memory leak and I am unable to identify the line in the source code that this occurs. Is this possible in DrMemory? What is the correct way to use this in order to identify/detect lines in the source code that cause the memory leak?
The log is below:
Dr. Memory version 1.7.0 build 5 built on Apr 4 2014 23:38:05
Dr. Memory results for pid 18240: "TestingDrMemory.exe"
Application cmdline: "TestingDrMemory.exe"
Recorded 104 suppression(s) from default C:\Program Files (x86)\Dr. Memory\bin\suppress-default.txt
===========================================================================
FINAL SUMMARY:
DUPLICATE ERROR COUNTS:
SUPPRESSIONS USED:
NO ERRORS FOUND:
0 unique, 0 total unaddressable access(es)
0 unique, 0 total uninitialized access(es)
0 unique, 0 total invalid heap argument(s)
0 unique, 0 total GDI usage error(s)
0 unique, 0 total handle leak(s)
0 unique, 0 total warning(s)
0 unique, 0 total, 0 byte(s) of leak(s)
0 unique, 0 total, 0 byte(s) of possible leak(s)
0 unique, 0 total, 0 byte(s) of still-reachable allocation(s)
ERRORS IGNORED:
2 potential error(s) (suspected false positives)
(details: C:\Dr. Memory\DrMemory-TestingDrMemory.exe.18240.000\potential_errors.txt)
18 potential leak(s) (suspected false positives)
(details: C:\Dr. Memory\DrMemory-TestingDrMemory.exe.18240.000\potential_errors.txt)
Details: C:\Dr. Memory\DrMemory-TestingDrMemory.exe.18240.000\results.txt
From the drmemory.org
If your application links with a static library that was built with frame pointer optimizations and you observe missing frames on your callstacks, try running with the Dr. Memory runtime options -no_callstack_use_top_fp, -no_callstack_use_fp, and -callstack_conservative. These will add some additional overhead on malloc-intensive applications, but should eliminate skipped frames.
Try running drmem with -batch -no_callstack_use_fp -no_callstack_use_top_fp
I have a toy project which is a game engine. It uses SDL2 and C++11. In the code below I tried to make an objects which cleans memory after itself in destructor. But something goes wrong and some memory leaks. What am I doing wrong?
Example is minimal working code which triggers a leak. I suppose it works like this:
Instance of class Game upon costruction creates instances of SDLEngine and Graphics (in this order), both of which allocates some memory too. When game object is destroyed it calls destructors of Graphics and SDLEngine (in this order). If I add some printing in both of this destructors they are printed in the needed order. But valgrind thinks that memory allocated by SDL_Init() and SDL_CreateWindow() are leaked.
Edit: it is probably valgrind behaviour. I saw a similar question and similar warnings in the pretty basic SDL example: Why does valgrind say basic SDL program is leaking memory?
src/leak-test.cpp:
#include <SDL2/SDL.h>
#include <stdexcept>
class SDLEngine {
public:
SDLEngine() {
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
throw std::runtime_error("SDL_Init"); // line 7
}
if (SDL_ShowCursor(SDL_DISABLE) < 0) {
throw std::runtime_error("SDL_ShowCursor");
}
}
~SDLEngine() {
SDL_Quit();
}
};
class Graphics {
public:
Graphics() :
sdlWindow{SDL_CreateWindow(
"LeakTest",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
320, 240,
0
)} // line 27
{
if (sdlWindow == nullptr) {
throw std::runtime_error("SDL_CreateWindow");
}
}
~Graphics() {
SDL_DestroyWindow(sdlWindow);
}
Graphics(const Graphics&)=delete;
Graphics& operator=(const Graphics&)=delete;
private:
SDL_Window *sdlWindow;
};
class Game {
public:
Game() :
sdlEngine_(),
graphics_() // line 46
{
SDL_Event event;
bool running{true};
while (running) {
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_KEYDOWN:
running = false;
break;
default:
break;
}
}
}
}
~Game() {}
private:
const SDLEngine sdlEngine_;
Graphics graphics_;
};
int main() {
Game game; // line 70
return 0;
}
Makefile:
CXX := g++
MKDIR := mkdir -p
CXXFLAGS += `pkg-config --cflags sdl2 SDL2_image`
CXXFLAGS += -Wall -Werror -Wextra -Weffc++ -pedantic -std=c++0x -g
LDFLAGS += `pkg-config --libs sdl2 SDL2_image`
PROG := bin/leak-test
OBJS := $(patsubst src/%.cpp,obj/%.o, $(wildcard src\/*.cpp))
# escaped to fool SO parser ^
.PHONY: all clean
all: build
build: $(PROG)
clean:
rm -rf $(PROG) $(OBJS)
$(PROG): obj/leak-test.o
$(PROG):
#$(MKDIR) $(dir $#)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $# $^
obj/%.o : src/%.cpp
#$(MKDIR) $(dir $#)
$(CXX) $(CXXFLAGS) -c -MD -o $# $<
Valgrind output:
host:cave-test » valgrind --leak-check=full ./bin/leak-test
==28815== Memcheck, a memory error detector
==28815== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==28815== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==28815== Command: ./bin/leak-test
==28815==
==28815==
==28815== HEAP SUMMARY:
==28815== in use at exit: 66,235 bytes in 506 blocks
==28815== total heap usage: 19,844 allocs, 19,338 frees, 44,931,400 bytes allocated
==28815==
==28815== 20 bytes in 2 blocks are definitely lost in loss record 7 of 101
==28815== at 0x4C274A0: malloc (vg_replace_malloc.c:291)
==28815== by 0x5BF8829: strdup (strdup.c:42)
==28815== by 0x7203666: ??? (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x7204474: _XimSetICValueData (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x71FFA69: _XimLocalCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x71E6044: XCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x5111CD2: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x51120F7: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x51055FF: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x510540F: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x507048E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x400D6E: SDLEngine::SDLEngine() (leak-test.cpp:7)
==28815==
==28815== 20 bytes in 2 blocks are definitely lost in loss record 8 of 101
==28815== at 0x4C274A0: malloc (vg_replace_malloc.c:291)
==28815== by 0x5BF8829: strdup (strdup.c:42)
==28815== by 0x7203666: ??? (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x7204474: _XimSetICValueData (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x71FFA69: _XimLocalCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x71E6044: XCreateIC (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)
==28815== by 0x5111CD2: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x51120F7: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x51055FF: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x400F11: Graphics::Graphics() (leak-test.cpp:27)
==28815== by 0x401012: Game::Game() (leak-test.cpp:46)
==28815== by 0x400D31: main (leak-test.cpp:70)
==28815==
==28815== 104 bytes in 1 blocks are definitely lost in loss record 60 of 101
==28815== at 0x4C274A0: malloc (vg_replace_malloc.c:291)
==28815== by 0xD330A11: ??? (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815== by 0xD309600: ??? (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815== by 0xD305E7A: ??? (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815== by 0xD30660F: glXChooseVisual (in /usr/lib/mesa-diverted/x86_64-linux-gnu/libGL.so.1.2.0)
==28815== by 0x510ED0E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x510EF40: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x5103B65: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x51056FB: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x510540F: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x507048E: ??? (in /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0.2.0)
==28815== by 0x400D6E: SDLEngine::SDLEngine() (leak-test.cpp:7)
==28815==
==28815== LEAK SUMMARY:
==28815== definitely lost: 144 bytes in 5 blocks
==28815== indirectly lost: 0 bytes in 0 blocks
==28815== possibly lost: 0 bytes in 0 blocks
==28815== still reachable: 66,091 bytes in 501 blocks
==28815== suppressed: 0 bytes in 0 blocks
==28815== Reachable blocks (those to which a pointer was found) are not shown.
==28815== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==28815==
==28815== For counts of detected and suppressed errors, rerun with: -v
==28815== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 7 from 3)
It turns out this leak belongs to layer under SDL, in the X11 library. This bug is very old and known by SDL devs. See this bugzilla thread: https://bugzilla.libsdl.org/show_bug.cgi?id=2086
I close the question now.
For a school project, we have to send big files across the network., we must use Poco::XML for our data.
After our files are send over the network, it appears that the memory does not free.
Here is an example for a file of ~9 Mb on the receiving part:
valgrind --leak-check=full --show-reachable=yes -v ourExecutable parms returns:
12,880,736 bytes in 37 blocks are definitely lost in loss record 101 of 101
at 0x4C2747E: operator new(unsigned long) (vg_replace_malloc.c:261)
by 0x5A3AC88: std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.4/libstdc++.so.6.0.13)
by 0x5A3BC4A: std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.4/libstdc++.so.6.0.13)
by 0x5A3C1BB: std::string::reserve(unsigned long) (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.4/libstdc++.so.6.0.13)
by 0x5A3C68E: std::string::append(std::string const&) (in /usr/lib64/gcc/x86_64-pc-linux-gnu/4.4.4/libstdc++.so.6.0.13)
by 0x5202359: Poco::XML::Element::innerText() const (in /home/tomwij/IGS/trunk/Project/external/lib/libPocoXML.so.8)
by 0x4145BF: NodeProtocol::getChildNodeStrValue(Poco::XML::Element*, std::string) (NodeProtocol.cpp:82)
by 0x41544F: NodeProtocol::deserialize(std::string const&) (NodeProtocol.cpp:200)
by 0x40B088: Node::handleClientPacket(PriorityElement*) (Node.cpp:760)
by 0x40A04C: Node::handlePackets() (Node.cpp:574)
by 0x4078EA: Node::run() (Node.cpp:162)
by 0x40772D: Node::activate() (Node.cpp:138)
LEAK SUMMARY:
definitely lost: 12,888,036 bytes in 190 blocks
indirectly lost: 644,979 bytes in 1,355 blocks
possibly lost: 10,089 bytes in 27 blocks
still reachable: 306,020 bytes in 43 blocks
suppressed: 0 bytes in 0 blocks
The function which is right before Poco is
const string NodeProtocol::getChildNodeStrValue(Element * elem, string child)
{
Element* tempNode = elem->getChildElement(child);
XMLString result(tempNode->innerText());
string ret = string(fromXMLString(result));
result.clear();
return ret;
}
which calls
XMLString Element::innerText() const
{
XMLString result;
Node* pChild = firstChild();
while (pChild)
{
result.append(pChild->innerText());
pChild = pChild->nextSibling();
}
return result;
}
(Note that XMLString is std::string)
Why is the append of STL string leaking memory?
If I just assign instead of using the copy constructors it gives the same problem.
EDIT:
I'm using the latest stable GNU GCC 4.4.4 on Gentoo x64 (linux-2.6.34-gentoo-r12).
More functions from the call stack (stripped irrelevant big chunks of code / if structures):
Command * NodeProtocol::deserialize(const string & msg)
{
DOMParser xmlParser;
// Get the root node.
AutoPtr<Document> doc = xmlParser.parseString(msg);
AutoPtr<Element> rootElement = doc->documentElement();
string root = fromXMLString(rootElement->nodeName());
string name = getChildNodeStrValue(rootElement, "name");
string data = getChildNodeStrValue(rootElement, "data");
return new PutCommand(name, data);
}
and
void Node::handleClientPacket(PriorityElement * prio)
{
Command * command = NodeProtocol::deserialize(prio->fPacket);
// CUT: Access some properties of command, let the command execute.
delete command;
}
and
void Node::handlePackets()
{
PriorityElement * prio = fQueue->top();
fQueue->pop();
if (prio->fSource == kCLIENT)
handleClientPacket(prio);
else if (prio->fSource == kNODE)
handleNodePacket(prio);
delete prio;
}
where fQueue is:
priority_queue< PriorityElement*, vector<PriorityElement*>, ComparisonFunction >
I would make this a comment, but apparently I don't have the rep. Have you remembered to make the destructor for Command virtual? If name or data are fields of PutCommand rather than Command and the Command destructor is not virtual, they may not be freed properly when you delete command in handleClientPacket.