Hi all,
I have written a very simple class to use it with ports. Y have
used StructTypeInfo and the serialization function.
Compiling all goes fine but executing MyTask with the deployer I can't do
cd "MyTask" because it causes a segmentation fault,
moreover if I do ctrl-d I obtain the error" glibc detected ***
deployer-gnulinux: double free or corruption".
I have found that the errors disappear if I eliminate the destructor of the
class that I use in the ports but as I'm using dynamical
memory allocation I'm not sure if the memory is correctly free.
The code of the class used for the ports is:
#include <rtt/types/TemplateTypeInfo.hp
#include <rtt/types/StructTypeInfo.hp
using namespace RTT;
using namespace std;
class stream
{
private:
unsigned char* streamp;
unsigned int internalSize;
public:
stream()
{
streamp=new unsigned char[1];
internalSize=1;
initialize();}
stream(unsigned int dim)
{
streamp=new unsigned char[dim];
internalSize=dim; }
//Commented to avoid the error but that's right?
//~stream(){delete streamp;};
unsigned int size() const
{
return internalSize;}
void resize(unsigned int dim)
{
streamp=new unsigned char[dim];
internalSize=dim; }
unsigned char* pointer(unsigned int i) const
{
return &streamp[i];}
unsigned char* & getStreamp()
{
unsigned char* &streampref=streamp;
return streampref;}
unsigned int & getInternalSize()
{
unsigned int &internalSizeref= internalSize;
return internalSizeref;}
};
// Displaying:
std::ostream& operator<< (std::ostream &os,const stream &cd) {
os << "[ ";
for (int i=0;i<cd.size();i++)
{
os << (int) *cd.pointer(i)<<" ";
}
os << ']';
return os;
}
std::istream& operator>> (std::istream &is, stream &cd) {
char c;
is >> c;
for (int i=0;i<cd.size();i++)
{
is >> *cd.pointer(i) >> c;
}
return is;
}
namespace boost {
namespace serialization {
// The helper function which you write yourself:
template<class Archive>
void serialize( Archive & a, stream & cd, unsigned int) {
using boost::serialization::make_nvp;
a & make_nvp("streamp", cd.getStreamp());
a & make_nvp("size", cd.getInternalSize());
}}}
// The RTT helper class which uses the above function behind the scenes:
struct streamTypeInfo
: public RTT::types::StructTypeInfo<stream,true>
{
streamTypeInfo()
: RTT::types::StructTypeInfo<stream,true>("stream")
{}
};
Thanks for any hint
Best regards
Luca
glibc detected *** deployer-gnulinux: double free or corruption
On Sun, Jun 10, 2012 at 7:37 PM, Luca Magnabosco
<magnabosco [dot] luca [..] ...>wrote:
> Hi all,
> I have written a very simple class to use it with ports. Y have
> used StructTypeInfo and the serialization function.
> Compiling all goes fine but executing MyTask with the deployer I can't do
> cd "MyTask" because it causes a segmentation fault,
> moreover if I do ctrl-d I obtain the error" glibc detected ***
> deployer-gnulinux: double free or corruption".
> I have found that the errors disappear if I eliminate the destructor of
> the class that I use in the ports but as I'm using dynamical
> memory allocation I'm not sure if the memory is correctly free.
>
> The code of the class used for the ports is:
>
> #include <rtt/types/TemplateTypeInfo.hp
> #include <rtt/types/StructTypeInfo.hp
>
> using namespace RTT;
> using namespace std;
>
> class stream
> {
> private:
> unsigned char* streamp;
> unsigned int internalSize;
>
> public:
> stream()
> {
> streamp=new unsigned char[1];
> internalSize=1;
> initialize();}
>
>
> stream(unsigned int dim)
> {
> streamp=new unsigned char[dim];
> internalSize=dim; }
>
> //Commented to avoid the error but that's right?
> //~stream(){delete streamp;};
>
You need to use delete[] streamp;, although that is not causing your double
free.
Second, you forgot to implement your copy constructor. RTT data types must
be copyable, and if your data is non-POD, you need to implement it yourself:
stream( const stream& orig )
{
streamp=new unsigned char[ orig.internalSize ];
internalSize = orig.internalSize();
memcpy( (void*)streamp, (void*)orig.streamp, internalSize);
}
> unsigned int size() const
> {
> return internalSize;}
>
> void resize(unsigned int dim)
> {
>
> streamp=new unsigned char[dim];
> internalSize=dim; }
>
>
> unsigned char* pointer(unsigned int i) const
> {
> return &streamp[i];}
>
> unsigned char* & getStreamp()
> {
> unsigned char* &streampref=streamp;
> return streampref;}
>
> unsigned int & getInternalSize()
> {
> unsigned int &internalSizeref= internalSize;
> return internalSizeref;}
>
Why not: return internalSize; ?
Why on earth aren't you using std::vector<unsigned int> ?!
Whatever your level of C++ knowledge, you shouldn't be writing classes like
this and only re-use the standard or Boost classes, which won't have these
kinds of bugs.
Peter
glibc detected *** deployer-gnulinux: double free or corruption
Hi all, hi Peter,
>You need to use delete[] streamp;, although that is not causing your double free.
>Second, you forgot to implement your copy constructor. RTT data types must be copyable, and if your data is non-POD, you need to >implement it yourself:
>stream( const stream& orig )
>{
> streamp=new unsigned char[ orig.internalSize ];
> internalSize = orig.internalSize();
> memcpy( (void*)streamp, (void*)orig.streamp, internalSize);
>}
Thanks, I have corrected the code as you said but I'm still facing errors:
-when using "cd" in the deployer I have a segmentation fault
-when I only try to close the deployer a double free
And cancelling "~PDOstream(){delete[] streamp;}; " all goes well so
I'm a little bit confused. What I'm not doing in the right way?
>Why not: return internalSize;
Of course...it was a silly error...thanks..
>Why on earth aren't you using std::vector<unsigned int> ?!
I was interested in unsigned char vector...and I have already tried
the code with it...This stream class is only a simple class to
understand and try.
Moreover I was trying to use a different class to overload operator<<
as the normal one for vector is not so good in my case.
>Whatever your level of C++ knowledge, you shouldn't be writing classes like this and only re-use the standard or Boost classes, which >won't have these kinds of bugs.
Of course I will avoid writing class :) but I was trying to learn, and
as I was reading from the manual, I haven't understand yet where I
have made the error that let the programs communicate well but cause a
fault when using "cd" in the deployer.
Best regards
Luca
glibc detected *** deployer-gnulinux: double free or corruption
On Mon, Jun 18, 2012 at 9:32 PM, Luca Magnabosco
<magnabosco [dot] luca [..] ...>wrote:
> Hi all, hi Peter,
>
> >You need to use delete[] streamp;, although that is not causing your
> double free.
> >Second, you forgot to implement your copy constructor. RTT data types
> must be copyable, and if your data is non-POD, you need to >implement it
> yourself:
>
> >stream( const stream& orig )
> >{
> > streamp=new unsigned char[ orig.internalSize ];
> > internalSize = orig.internalSize();
> > memcpy( (void*)streamp, (void*)orig.streamp, internalSize);
> >}
>
> Thanks, I have corrected the code as you said but I'm still facing errors:
> -when using "cd" in the deployer I have a segmentation fault
> -when I only try to close the deployer a double free
> And cancelling "~PDOstream(){delete[] streamp;}; " all goes well so
> I'm a little bit confused. What I'm not doing in the right way?
>
> >Why not: return internalSize;
> Of course...it was a silly error...thanks..
>
> >Why on earth aren't you using std::vector<unsigned int> ?!
> I was interested in unsigned char vector...and I have already tried
> the code with it...This stream class is only a simple class to
> understand and try.
> Moreover I was trying to use a different class to overload operator<<
> as the normal one for vector is not so good in my case.
>
> >Whatever your level of C++ knowledge, you shouldn't be writing classes
> like this and only re-use the standard or Boost classes, which >won't have
> these kinds of bugs.
>
> Of course I will avoid writing class :) but I was trying to learn, and
> as I was reading from the manual, I haven't understand yet where I
> have made the error that let the programs communicate well but cause a
> fault when using "cd" in the deployer.
>
Run the deployer under a valgrind process and see what it tells you. Make
sure you're running a Debug build.
Peter