Dear Romain, Dirk, and Qiang, Thanks for Romain's reminder of auto appended catch block, Dirk's explanation of leaks and exception and Qiang's simple example. Now I understand that an uncaught exception in a c++ program might cause memory leak. A SO Q&A ( http://stackoverflow.com/questions/27677895/valgrind-detects-errors-when-c-exception-is-not-caught) also makes me believe that it is normal for c++ program. You are right, it is normal for a simple C++ program.
However, I want to argue that it might be a bug for Rcpp, or Rcpp Attributes. For example, a package developer might use c++ exception as an error in R because he/she believes Rcpp Attributes will transform it automatically. An user might use the `tryCatch` in R to skip the error and keep his R process working, so the leaking might make trouble for the user. I verify my though by repeating the `tryCatch` block in R and the number of lost blocks reported by valgrind is increasing. This behaviour makes me uncomfortable since I think it is OK to pass a c++ exception to R and Rcpp Attributes will automatically transfer the exception to R error. I think we could solve it if the we close the c++ scope properly before raising an error to R. That is to say, we could modify the macro VOID_END_RCPP to avoid this error. To verify my though, I modify the generated src/RcppExports.cpp as follow: // test1 std::string except_message; bool is_ex; void test1(); RcppExport SEXP RcppMemTest_test1() { is_ex = false; try { { Rcpp::RNGScope __rngScope; test1(); } return R_NilValue; } catch( std::exception& __ex__ ){ except_message.assign(__ex__.what()); is_ex = true; } if (is_ex) { forward_exception_to_r(std::logic_error(except_message)); } Now the lost block does not increase if the `tryCatch` block in R increases. If you agree that it is a bug, I am happy to send a pull request and we could discuss more details there. Best, Wush 2014-12-30 11:32 GMT+08:00 Qiang Kou <q...@umail.iu.edu>: > Hi, Wush, > > It seems that memory leakage has nothing to do with R. > > Just use your code without R: > > #include <iostream> > #include <stdexcept> > > int main(int argc, char **argv) { > > std::string msg = std::string("test"); > throw std::logic_error(msg); > return 0; > } > > I still get the same leakage information: > > ==19532== Memcheck, a memory error detector > ==19532== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. > ==19532== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for > copyright info > ==19532== Command: ./a.out > ==19532== > terminate called after throwing an instance of 'std::logic_error' > what(): test > ==19532== > ==19532== HEAP SUMMARY: > ==19532== in use at exit: 173 bytes in 2 blocks > ==19532== total heap usage: 3 allocs, 1 frees, 205 bytes allocated > ==19532== > ==19532== LEAK SUMMARY: > ==19532== definitely lost: 0 bytes in 0 blocks > ==19532== indirectly lost: 0 bytes in 0 blocks > ==19532== possibly lost: 173 bytes in 2 blocks > ==19532== still reachable: 0 bytes in 0 blocks > ==19532== suppressed: 0 bytes in 0 blocks > ==19532== Rerun with --leak-check=full to see details of leaked memory > ==19532== > ==19532== For counts of detected and suppressed errors, rerun with: -v > ==19532== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) > *Aborted (core dumped)* > > The program may abort before releasing the resource, so there may be > memory leak. > > With try/catch, the program will exit normally. So no leakage found. > > Best, > > KK > > > On Mon, Dec 29, 2014 at 10:05 PM, Dirk Eddelbuettel <e...@debian.org> > wrote: > >> >> PS Here is a better variant that actually leaks: >> >> edd@max:/tmp$ cat leak.cpp >> >> #include <cstdio> >> #include <cstdlib> >> #include <iostream> >> #include <cmath> >> >> int main() { >> double *d = new double[1024]; >> if (d) std::cout << "Allocated" << std::endl; >> double e = std::exp(1.0); >> d = &e; >> exit(0); >> } >> edd@max:/tmp$ g++ -Wall -o leak leak.cpp >> edd@max:/tmp$ valgrind ./leak >> ==16924== Memcheck, a memory error detector >> ==16924== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. >> ==16924== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright >> info >> ==16924== Command: ./leak >> ==16924== >> Allocated >> ==16924== >> ==16924== HEAP SUMMARY: >> ==16924== in use at exit: 8,192 bytes in 1 blocks >> ==16924== total heap usage: 1 allocs, 0 frees, 8,192 bytes allocated >> ==16924== >> ==16924== LEAK SUMMARY: >> ==16924== definitely lost: 8,192 bytes in 1 blocks >> ==16924== indirectly lost: 0 bytes in 0 blocks >> ==16924== possibly lost: 0 bytes in 0 blocks >> ==16924== still reachable: 0 bytes in 0 blocks >> ==16924== suppressed: 0 bytes in 0 blocks >> ==16924== Rerun with --leak-check=full to see details of leaked memory >> ==16924== >> ==16924== For counts of detected and suppressed errors, rerun with: -v >> ==16924== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) >> edd@max:/tmp$ >> >> By overwriting d the memory is lost for good, and valgrind notices as >> you;d >> think it would. >> >> Dirk >> >> -- >> http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org >> _______________________________________________ >> Rcpp-devel mailing list >> Rcpp-devel@lists.r-forge.r-project.org >> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel >> > > > > -- > Qiang Kou > q...@umail.iu.edu > School of Informatics and Computing, Indiana University > >
_______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel