I'm trying out boost threads and I noticed from valgrind that it is leaking 320 bytes just from looping through an empty block of code. I found some posts on google from 2010 that suggests that they are likely a false positive from threads not closing before valgind runs through, but this is slightly different. In those examples you had a few blocks that were still reachable (therefor, freeable if threads were still running) where my run shows 8 as still reachable and 20 blocks as definitely lost. Is this something I should worry about, or am I somehow missing something? Thanks
The code
#include <boost/thread.hpp>
#include <iostream>
#define THREADS 20
void threadfunc(int workerid) {}
int main(int argc, char **argv){
boost::thread *threads[THREADS];
int i;
for (i = 0; i < THREADS; i++) {
threads[i] = new boost::thread(threadfunc, i);
}
for (i = 0; i < THREADS; i++) {
threads[i]->join();
}
}
Compile command
c++ -o example example.cpp -I /usr/include/boost -lboost_system -lboost_thread
Valgind command
G_SLICE=always-malloc G_DEBUG=gc-friendly valgrind -v --tool=memcheck --leak-check=full --show-reachable=yes --num-callers=40 --log-file=valgrind.log ./example
Valgine results
==31674== HEAP SUMMARY:
==31674== in use at exit: 328 bytes in 21 blocks
==31674== total heap usage: 103 allocs, 82 frees, 14,968 bytes allocated
==31674==
==31674== Searching for pointers to 21 not-freed blocks
==31674== Checked 215,920 bytes
==31674==
==31674== 8 bytes in 1 blocks are still reachable in loss record 1 of 2
==31674== at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==31674== by 0x4E454A9: boost::detail::get_once_per_thread_epoch() (in /usr/lib/libboost_thread.so.1.46.1)
==31674== by 0x4E3E4FF: ??? (in /usr/lib/libboost_thread.so.1.46.1)
==31674== by 0x4E3E7C8: boost::detail::get_current_thread_data() (in /usr/lib/libboost_thread.so.1.46.1)
==31674== by 0x4E3FF3A: boost::thread::join() (in /usr/lib/libboost_thread.so.1.46.1)
==31674== by 0x402C79: main (in /home/Jason/php/base/example)
==31674==
==31674== 320 bytes in 20 blocks are definitely lost in loss record 2 of 2
==31674== at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==31674== by 0x402C2A: main (in /home/Jason/php/base/example)
==31674==
==31674== LEAK SUMMARY:
==31674== definitely lost: 320 bytes in 20 blocks
==31674== indirectly lost: 0 bytes in 0 blocks
==31674== possibly lost: 0 bytes in 0 blocks
==31674== still reachable: 8 bytes in 1 blocks
==31674== suppressed: 0 bytes in 0 blocks
==31674==
==31674== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
--31674--
--31674-- used_suppression: 2 dl-hack3-cond-1
==31674==
==31674== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
It's your errors, not boost::threads.
Your memory are not freed.
for (i = 0; i < THREADS; i++) {
threads[i] = new boost::thread(threadfunc, i);
}
Before exit from main function you must free memory (delete threads).
Something like
for (i = 0; i < THREADS; i++) {
delete threads[i];
}
or delete next after join.
Related
#include <iostream>
#include <random>
int main()
{
int a;
int *arr;
a = 3;
arr = new int[a];
#pragma omp parallel for
for (int i = 0; i < a; i++)
arr[i] = i;
delete[] arr;
return 0;
}
When I test this simple code with valgrind, it saids:
==2606== HEAP SUMMARY:
==2606== in use at exit: 3,360 bytes in 7 blocks
==2606== total heap usage: 10 allocs, 3 frees, 108,892 bytes allocated
==2606==
==2606== LEAK SUMMARY:
==2606== definitely lost: 0 bytes in 0 blocks
==2606== indirectly lost: 0 bytes in 0 blocks
==2606== possibly lost: 912 bytes in 3 blocks
==2606== still reachable: 2,448 bytes in 4 blocks
==2606== suppressed: 0 bytes in 0 blocks
Am I misunderstanding openmp or memory allocation usage?
Without "#pragma omp parallel for", it doesn't make any issues.
UPDATE
==2682== 912 bytes in 3 blocks are possibly lost in loss record 4 of 5
==2682== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==2682== by 0x40149DA: allocate_dtv (dl-tls.c:286)
==2682== by 0x40149DA: _dl_allocate_tls (dl-tls.c:532)
==2682== by 0x4DE4322: allocate_stack (allocatestack.c:622)
==2682== by 0x4DE4322: pthread_create##GLIBC_2.2.5 (pthread_create.c:660)
==2682== by 0x4A4FDEA: ??? (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==2682== by 0x4A478E0: GOMP_parallel (in /usr/lib/x86_64-linux-gnu/libgomp.so.1.0.0)
==2682== by 0x109184: main (main.cpp:10)
This is what --leak-check-full says.
Following is a section of the output of the log-file from Valgrind using the following command:
valgrind --leak-check=full --show-leak-kinds=all --verbose
--log-file=valgrind_output.txt ./TestMatlab
==12340==
==12340== HEAP SUMMARY:
==12340== in use at exit: 8,132 bytes in 99 blocks
==12340== total heap usage: 3,810 allocs, 3,711 frees, 436,330 bytes allocated
==12340==
==12340== Searching for pointers to 99 not-freed blocks
==12340== Checked 3,940,672 bytes
...
...
...
==12340== LEAK SUMMARY:
==12340== definitely lost: 0 bytes in 0 blocks
==12340== indirectly lost: 0 bytes in 0 blocks
==12340== possibly lost: 0 bytes in 0 blocks
==12340== still reachable: 8,132 bytes in 99 blocks
==12340== suppressed: 0 bytes in 0 blocks
==12340==
==12340== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==12340== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
The C++ program is a very simple code that just instantiates an object of the engine API for C++ interface and subsequently closes the engine interface. The code is shown below:
#include "engine.h"
#include <iostream>
#include <stdlib.h>
int main() {
Engine *ep;
if (!(ep = engOpen(""))) {
std::cout <<"\nCan't start MATLAB engine" << std::endl;
return EXIT_FAILURE;
}
std::cout << "Done!" << std::endl;
engClose(ep);
return 0;
}
Can this issue be fixed? If so how can I do it?
I'm trying to implement a function mergeSort that returns a dynamic array of type intervalo_t. As it is, the function is working nicely, the problem I have is that when I run Valgrind to check for memory loss, turns out I'm loosing quite a bit.
Intervalo_t definition:
struct intervalo_t {
nat inicio;
nat fin;
};
This is the code:
intervalo_t* mergeSort(intervalo_t *intervalos, nat n)
{
intervalo_t* ret=new intervalo_t[n];
if(n==2){
if (intervalos[0].fin>intervalos[1].fin){
ret[0]=intervalos[1];
ret[1]=intervalos[0];
}else{
ret[0]=intervalos[0];
ret[1]=intervalos[1];
}
//caso base
}else if (n==1){
ret[0]=intervalos[0];
//caso base
}else{
nat k=0;
if((n%2)!=0){
k=1;
}//Si es par o no
intervalo_t* interA =new intervalo_t[n/2 + k];
intervalo_t* interB =new intervalo_t[n/2];
for (nat i=0; i<n/2; i++){
interA[i]=intervalos[i];
interB[i]=intervalos[i+(n/2)];
}//for
if (k==1){
interA[(n/2)]=intervalos[n-1];
}
interA=mergeSort(interA, n/2 + k);
interB=mergeSort(interB, n/2);
nat i=0;
nat j=0;
nat r=0;
while((i<((n/2)+k)) && (j<(n/2))){
if (interA[i].fin>interB[j].fin){
ret[r]=interB[j];
j++;
}else{
ret[r]=interA[i];
i++;
}
r++;
}
while(i<(n/2)+k){
ret[r]=interA[i];
i++;
r++;
}
while(j<(n/2)){
ret[r]=interA[j];
i++;
j++;
}
delete[] interA;
delete[] interB;
//recursion
}
return ret;
}
And this is Valgrind's output:
==15556==
==15556== HEAP SUMMARY:
==15556== in use at exit: 24 bytes in 2 blocks
==15556== total heap usage: 12 allocs, 10 frees, 77,959 bytes allocated
==15556==
==15556== 8 bytes in 1 blocks are definitely lost in loss record 1 of 2
==15556== at 0x4C2F06F: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==15556== by 0x401536: mergeSort(intervalo_t*, unsigned int) (intervalos.cpp:26)
==15556== by 0x4017C3: max_cantidad(intervalo_t*, unsigned int) (intervalos.cpp:67)
==15556== by 0x401130: main (principal.cpp:170)
==15556==
==15556== 16 bytes in 1 blocks are definitely lost in loss record 2 of 2
==15556== at 0x4C2F06F: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==15556== by 0x401509: mergeSort(intervalo_t*, unsigned int) (intervalos.cpp:25)
==15556== by 0x4017C3: max_cantidad(intervalo_t*, unsigned int) (intervalos.cpp:67)
==15556== by 0x401130: main (principal.cpp:170)
==15556==
==15556== LEAK SUMMARY:
==15556== definitely lost: 24 bytes in 2 blocks
==15556== indirectly lost: 0 bytes in 0 blocks
==15556== possibly lost: 0 bytes in 0 blocks
==15556== still reachable: 0 bytes in 0 blocks
==15556== suppressed: 0 bytes in 0 blocks
==15556==
==15556== For lists of detected and suppressed errors, rerun with: -s
==15556== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
I ran valgrind with:
valgrind --leak-check=full ./myFile <test.in
Test.in:
mergeSort
15
30
45
Thanks in advance for your help!
The problem is that the memory you allocated here:
intervalo_t* interA =new intervalo_t[n/2 + k];
intervalo_t* interB =new intervalo_t[n/2];
leaks when you overwrite those pointers here:
interA=mergeSort(interA, n/2 + k);
interB=mergeSort(interB, n/2);
It is rarely a good idea to reuse variables for multiple purposes, so use separate variables for the recursive results:
intervalo_t* resultA=mergeSort(interA, n/2 + k);
intervalo_t* resultB=mergeSort(interB, n/2);
and then use those for merging (and remember to release them).
I would also recommend disposing of the inputs immediately after recursing so you don't forget it.
Or, you could use std::vector and save yourself some headaches.
I have a very simple C++ program.
#include <iostream>
int main()
{
std::cout << "HI" << std::endl;
return 0;
}
I compile this on a Mac with the command c++ --std=c++11 leak.cpp.
When I debug this with valgrind --leak-check=full ./a.out, I get the following output:
==2187== HEAP SUMMARY:
==2187== in use at exit: 38,906 bytes in 429 blocks
==2187== total heap usage: 508 allocs, 79 frees, 45,074 bytes allocated
==2187==
==2187== LEAK SUMMARY:
==2187== definitely lost: 0 bytes in 0 blocks
==2187== indirectly lost: 0 bytes in 0 blocks
==2187== possibly lost: 0 bytes in 0 blocks
==2187== still reachable: 4,096 bytes in 1 blocks
==2187== suppressed: 34,810 bytes in 428 blocks
==2187== Reachable blocks (those to which a pointer was found) are not shown.
==2187== To see them, rerun with: --leak-check=full --show-leak-kinds=all
Turns out there are 4096 bytes that are "still reachable". If I remove the cout statement then there are no more "still reachable" bytes.
Why is it the case that outputting to std::cout causes a memory leak?
It could be a false positive in the leak report. Valgrind can only be so clever; your standard library implementation is taking certain liberties that Valgrind doesn't have a special case for.
I'd be more worried about figuring out why this tiny program is performing 508 allocations, to a total of 45,074 bytes.
I'm atempting to learn xerces-c and was following this tutorial online.
http://www.yolinux.com/TUTORIALS/XML-Xerces-C.html
I was able to get the tutorial to compile and run through a memory checker (valgrind) with no problems however when I made alterations to the program slightly, the memory checker returned some potential leak bytes. I only added a few extra lines to main to allow the program to read two files instead of one.
int main()
{
string configFile="sample.xml"; // stat file. Get ambigious segfault otherwise.
GetConfig appConfig;
appConfig.readConfigFile(configFile);
cout << "Application option A=" << appConfig.getOptionA() << endl;
cout << "Application option B=" << appConfig.getOptionB() << endl;
// Added code
configFile = "sample1.xml";
appConfig.readConfigFile(configFile);
cout << "Application option A=" << appConfig.getOptionA() << endl;
cout << "Application option B=" << appConfig.getOptionB() << endl;
return 0;
}
I was wondering why is it when I added the extra lines of code to read in another xml file, it would result in the following output?
==776== Using Valgrind-3.6.0 and LibVEX; rerun with -h for copyright info
==776== Command: ./a.out
==776==
Application option A=10
Application option B=24
Application option A=30
Application option B=40
==776==
==776== HEAP SUMMARY:
==776== in use at exit: 6 bytes in 2 blocks
==776== total heap usage: 4,031 allocs, 4,029 frees, 1,092,045 bytes allocated
==776==
==776== 3 bytes in 1 blocks are definitely lost in loss record 1 of 2
==776== at 0x4C28B8C: operator new(unsigned long) (vg_replace_malloc.c:261)
==776== by 0x5225E9B: xercesc_3_1::MemoryManagerImpl::allocate(unsigned long) (MemoryManagerImpl.cpp:40)
==776== by 0x53006C8: xercesc_3_1::IconvGNULCPTranscoder::transcode(unsigned short const*, xercesc_3_1::MemoryManager*) (IconvGNUTransService.cpp:751)
==776== by 0x4038E7: GetConfig::readConfigFile(std::string&) (in /home/bonniehan/workspace/test/a.out)
==776== by 0x403B13: main (in /home/bonniehan/workspace/test/a.out)
==776==
==776== 3 bytes in 1 blocks are definitely lost in loss record 2 of 2
==776== at 0x4C28B8C: operator new(unsigned long) (vg_replace_malloc.c:261)
==776== by 0x5225E9B: xercesc_3_1::MemoryManagerImpl::allocate(unsigned long) (MemoryManagerImpl.cpp:40)
==776== by 0x53006C8: xercesc_3_1::IconvGNULCPTranscoder::transcode(unsigned short const*, xercesc_3_1::MemoryManager*) (IconvGNUTransService.cpp:751)
==776== by 0x40393F: GetConfig::readConfigFile(std::string&) (in /home/bonniehan/workspace/test/a.out)
==776== by 0x403B13: main (in /home/bonniehan/workspace/test/a.out)
==776==
==776== LEAK SUMMARY:
==776== definitely lost: 6 bytes in 2 blocks
==776== indirectly lost: 0 bytes in 0 blocks
==776== possibly lost: 0 bytes in 0 blocks
==776== still reachable: 0 bytes in 0 blocks
==776== suppressed: 0 bytes in 0 blocks
==776==
==776== For counts of detected and suppressed errors, rerun with: -v
==776== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 2 from 2)
Looks like the example code has some shortcomings for your use case. It contains this code:
m_OptionA = XMLString::transcode(xmlch_OptionA);
From the documentation we can see that transcode requires its caller to deallocate the returned (C-style) string with XMLString::release(). We can see that this is done in the GetConfig destructor:
if(m_OptionA) XMLString::release( &m_OptionA );
But this code does not exist in readConfig(). You should add it there. You may also want to initialize those C-style string members to NULL in the constructor, or you will face another memory problem (potentially a crash bug) if you call readConfig() zero times instead of one or two.