Hi Jason.

to pinpoint potential memory issues you may run your code through valgrind.
For example, it would flag access to previously freed memory in your
program:

     1  #include <GraphMol/RDKitBase.h>
     2  #include <GraphMol/SmilesParse/SmilesParse.h>
     3  #include <iostream>
     4
     5  int main() {
     6          auto mol = RDKit::SmilesToMol("CCCC");
     7          auto atom = mol->getAtomWithIdx(0);
     8          auto m2 = atom->getOwningMol();
     9          std::cout << "Z=" << atom->getAtomicNum() << std::endl;  //
prints Z=6
    10          delete mol;
    11          std::cout << "Z=" << atom->getIdx() << std::endl; // prints
Z=0
    12          std::cout << "N=" << m2.getNumAtoms() << std::endl;//
prints N=4
    13          delete atom; // seg fault
    14  }

$ valgrind ./testmem
==11551== Memcheck, a memory error detector
==11551== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==11551== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==11551== Command: ./testmem
==11551==
Z=6
==11551== Invalid read of size 4
==11551==    at 0x10C924: RDKit::Atom::getIdx() const (Atom.h:133)
==11551==    by 0x10B4B6: main (testmem.cpp:11)
==11551==  Address 0x5a85a84 is 52 bytes inside a block of size 72 free'd
==11551==    at 0x4C2B51D: operator delete(void*) (vg_replace_malloc.c:586)
==11551==    by 0x40A5F83: RDKit::ROMol::destroy() (in
/usr/prog/scicomp/pythonds/develop/conda/lib/libRDKitGraphMol.so.1.2020.03.5)
==11551==    by 0x40AC66E: RDKit::RWMol::~RWMol() (in
/usr/prog/scicomp/pythonds/develop/conda/lib/libRDKitGraphMol.so.1.2020.03.5)
==11551==    by 0x10B494: main (testmem.cpp:10)
==11551==  Block was alloc'd at
==11551==    at 0x4C2A593: operator new(unsigned long)
(vg_replace_malloc.c:344)
==11551==    by 0x4EA4F6B: yysmiles_lex(YYSTYPE*, void*, int&) (in
/usr/prog/scicomp/pythonds/develop/conda/lib/libRDKitSmilesParse.so.1.2020.03.5)
==11551==    by 0x4E99E8F: yysmiles_parse(char const*,
std::vector<RDKit::RWMol*, std::allocator<RDKit::RWMol*> >*, RDKit::Atom*&,
RDKit::Bond*&, std::__cxx11::list<unsigned int, std:
:allocator<unsigned int> >*, void*, int&) (in
/usr/prog/scicomp/pythonds/develop/conda/lib/libRDKitSmilesParse.so.1.2020.03.5)
==11551==    by 0x4E5B192: RDKit::(anonymous
namespace)::smiles_parse_helper(std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&, std::vector<RDKit:
:RWMol*, std::allocator<RDKit::RWMol*> >&, RDKit::Atom*&, RDKit::Bond*&,
int) (in
/usr/prog/scicomp/pythonds/develop/conda/lib/libRDKitSmilesParse.so.1.2020.03.5)
==11551==    by 0x4E5B5CA: RDKit::(anonymous
namespace)::smiles_parse(std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&,
std::vector<RDKit::RWMol*
, std::allocator<RDKit::RWMol*> >&) (in
/usr/prog/scicomp/pythonds/develop/conda/lib/libRDKitSmilesParse.so.1.2020.03.5)
==11551==    by 0x4E5CB24: RDKit::toMol(std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > const&, int
(*)(std::__cxx11::basic_string<char, std::char_trai
ts<char>, std::allocator<char> > const&, std::vector<RDKit::RWMol*,
std::allocator<RDKit::RWMol*> >&), std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> >
const&) (in
/usr/prog/scicomp/pythonds/develop/conda/lib/libRDKitSmilesParse.so.1.2020.03.5)
==11551==    by 0x4E63828:
RDKit::SmilesToMol(std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&, RDKit::SmilesParserParams const&) (in
/usr/prog/s
cicomp/pythonds/develop/conda/lib/libRDKitSmilesParse.so.1.2020.03.5)
==11551==    by 0x10D4B8:
RDKit::SmilesToMol(std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> > const&, int, bool,
std::map<std::__cxx11::basic_string<cha
r, std::char_traits<char>, std::allocator<char> >,
std::__cxx11::basic_string<char, std::char_traits<char>,
std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::cha
r_traits<char>, std::allocator<char> > >,
std::allocator<std::pair<std::__cxx11::basic_string<char,
std::char_traits<char>, std::allocator<char> > const,
std::__cxx11::basic_string<ch
ar, std::char_traits<char>, std::allocator<char> > > > >*)
(SmilesParse.h:79)
==11551==    by 0x10B3DC: main (testmem.cpp:6)
==11551==

Cheers,
p.

On Thu, Aug 27, 2020 at 9:17 PM Jason Biggs <jasondbi...@gmail.com> wrote:

> Everything I know about C++ I learned just so that I can write a link
> between an interpreted language and the rdkit, so there are definitely some
> gaps in my knowledge.
>
> What I'm trying to understand right now is the expected lifetime of an
> Atom pointer returned by a molecule, for instance by the getAtomWithIdx
> method.  Based on the documentation, since this method doesn't say the user
> is responsible for deleting the returned pointer I know I'm not supposed to
> delete it. But when exactly does it get deleted?  If I dereference it after
> deleting the molecule, what is it?
>
> auto mol = RDKit::SmilesToMol("CCCC");
> auto atom = mol->getAtomWithIdx(0);
> auto m2 = atom->getOwningMol();
> std::cout << "Z=" << atom->getAtomicNum() << std::endl;  // prints Z=6
> delete mol;
> std::cout << "Z=" << atom->getIdx() << std::endl; // prints Z=0
> std::cout << "N=" << m2.getNumAtoms() << std::endl;// prints N=4
> delete atom; // seg fault
>
> I would have thought the first time dereferencing the atom pointer after
> deleting mol would have crashed, but it does not.  I would also have
> expected bad things when calling the getNumAtoms method on m2 after calling
> delete on mol, but this also works just fine.  What am I missing?
>
> Thanks
> Jason
> _______________________________________________
> Rdkit-discuss mailing list
> Rdkit-discuss@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/rdkit-discuss
>
_______________________________________________
Rdkit-discuss mailing list
Rdkit-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rdkit-discuss

Reply via email to