min_element algorithm and function object copying

Discussion in 'C++' started by suresh, Sep 11, 2010.

  1. suresh

    suresh Guest

    Hi,
    In my code, the operator() method of a function object is designed to
    fill a set which is a private data member of the function object. This
    function object is used in min_element algorithm.
    Since the min_element algorithm uses a copy of the function object (as
    per my understanding - hoping it to be true), I am unable to access
    the set data member of the function object. A minimal code is show
    below:

    class FO{
    public:
    bool operator()(int a, int b);
    private:
    set<int> s;
    };
    bool FO::eek:perator()(int a,int b){
    s.insert(a);
    return (a<b);
    }
    vector<int> v;
    //vector populated
    FO fo;
    min_element(v.begin(),v.end(),fo);

    Only after some time I realised that min_element takes only a copy of
    the variable fo. [I found that the size of the set is always zero
    after the call to min_element]. As a solution to this problem, I
    tried to define the variable s as a pointer to set (set<int> *s) and
    then modified the code accordingly but when the code is running, half
    way thru, the code aborts saying corrupted double-linked list:
    0x000000000102beb0 ***.

    What is the solution to this issue?

    Thanks
    suresh
    suresh, Sep 11, 2010
    #1
    1. Advertising

  2. * suresh, on 11.09.2010 03:24:
    > Hi,
    > In my code, the operator() method of a function object is designed to
    > fill a set which is a private data member of the function object. This
    > function object is used in min_element algorithm.
    > Since the min_element algorithm uses a copy of the function object (as
    > per my understanding - hoping it to be true), I am unable to access
    > the set data member of the function object. A minimal code is show
    > below:
    >
    > class FO{
    > public:
    > bool operator()(int a, int b);
    > private:
    > set<int> s;
    > };
    > bool FO::eek:perator()(int a,int b){
    > s.insert(a);
    > return (a<b);
    > }
    > vector<int> v;
    > //vector populated
    > FO fo;
    > min_element(v.begin(),v.end(),fo);
    >
    > Only after some time I realised that min_element takes only a copy of
    > the variable fo. [I found that the size of the set is always zero
    > after the call to min_element]. As a solution to this problem, I
    > tried to define the variable s as a pointer to set (set<int> *s) and
    > then modified the code accordingly but when the code is running, half
    > way thru, the code aborts saying corrupted double-linked list:
    > 0x000000000102beb0 ***.
    >
    > What is the solution to this issue?


    Depends on the dog, to paraphrase Niels Bohr.

    Try again with the pointer but set it to point at a setd::set variable at the
    call site.

    If you can't get that to work, post a complete but minimum program exhibiting
    the problem.


    Cheers & hth.,

    - Alf


    --
    blog at <url: http://alfps.wordpress.com>
    Alf P. Steinbach /Usenet, Sep 11, 2010
    #2
    1. Advertising

  3. suresh

    suresh Guest

    On Sep 10, 6:39 pm, "Alf P. Steinbach /Usenet" <alf.p.steinbach
    > wrote:
    > * suresh, on 11.09.2010 03:24:
    >
    > > Hi,
    > > In my code, the operator() method of a function object  is designed to
    > > fill a set which is a private data member of the function object. This
    > > function object is used in min_element algorithm.
    > > Since the min_element algorithm uses a copy of the function object (as
    > > per my understanding - hoping it to be true), I am unable to access
    > > the set data member of the function object.  A minimal code is show
    > > below:

    >
    > > class FO{
    > > public:
    > > bool operator()(int a, int b);
    > > private:
    > > set<int>  s;
    > > };
    > > bool FO::eek:perator()(int a,int b){
    > > s.insert(a);
    > > return (a<b);
    > > }
    > > vector<int>  v;
    > > //vector populated
    > > FO fo;
    > > min_element(v.begin(),v.end(),fo);

    >
    > > Only after some time I realised that min_element takes only a copy of
    > > the variable fo. [I found that the size of the set is always zero
    > > after the call to  min_element]. As a solution to this problem, I
    > > tried to define the variable s as a pointer to set (set<int>  *s) and
    > > then modified the code accordingly but when the code is running, half
    > > way thru, the code aborts saying  corrupted double-linked list:
    > > 0x000000000102beb0 ***.

    >
    > > What is the solution to this issue?

    >
    > Depends on the dog, to paraphrase Niels Bohr.
    >
    > Try again with the pointer but set it to point at a setd::set variable at the
    > call site.
    >
    > If you can't get that to work, post a complete but minimum program exhibiting
    > the problem.


    what is setd::set? Or you meant std::set?
    suresh
    suresh, Sep 11, 2010
    #3
  4. * suresh, on 11.09.2010 03:43:
    >
    > what is setd::set? Or you meant std::set?
    > suresh


    Yes, my keyboard gremlin got a little too much water.


    Cheers,

    - Alf

    --
    blog at <url: http://alfps.wordpress.com>
    Alf P. Steinbach /Usenet, Sep 11, 2010
    #4
  5. suresh

    suresh Guest

    On Sep 10, 6:50 pm, "Alf P. Steinbach /Usenet" <alf.p.steinbach
    > wrote:
    > * suresh, on 11.09.2010 03:43:
    >
    >
    >
    > > what is setd::set? Or  you meant std::set?
    > > suresh

    >
    > Yes, my keyboard gremlin got a little too much water.


    I am unable to reproduce the error in a smaller code bcz it works
    fine...but in my main code, it says

    *** glibc detected *** ./multSim: corrupted double-linked list:
    0x00000000011cb030 ***
    ======= Backtrace: =========
    /lib/libc.so.6(+0x775b6)[0x7f8176f4f5b6]
    /lib/libc.so.6(+0x77a1f)[0x7f8176f4fa1f]
    /lib/libc.so.6(+0x7a460)[0x7f8176f52460]
    /lib/libc.so.6(cfree+0x73)[0x7f8176f55e53]
    ../multSim[0x40bba6]
    ../multSim[0x4128f6]
    ../multSim[0x412b86]
    ../multSim[0x4089e9]
    ../multSim[0x4140a7]
    ../multSim[0x41362b]
    ../multSim[0x411940]
    /lib/libc.so.6(__libc_start_main+0xfd)[0x7f8176ef6c4d]
    ../multSim[0x4032c9]
    ======= Memory map: ========
    00400000-0041c000 r-xp 00000000 08:32 15991583
    and similar lines....

    in such a situation, is there any generic approach for finding the
    bug?
    thanks
    suresh
    suresh, Sep 11, 2010
    #5
  6. suresh

    suresh Guest

    On Sep 10, 7:59 pm, suresh <> wrote:
    > On Sep 10, 6:50 pm, "Alf P. Steinbach /Usenet" <alf.p.steinbach
    >
    > > wrote:
    > > * suresh, on 11.09.2010 03:43:

    >
    > > > what is setd::set? Or  you meant std::set?
    > > > suresh

    >
    > > Yes, my keyboard gremlin got a little too much water.

    >
    > I am unable to reproduce the error in a smaller code bcz it works
    > fine...but in my main code, it says
    >
    > *** glibc detected *** ./multSim: corrupted double-linked list:
    > 0x00000000011cb030 ***
    > ======= Backtrace: =========
    > /lib/libc.so.6(+0x775b6)[0x7f8176f4f5b6]
    > /lib/libc.so.6(+0x77a1f)[0x7f8176f4fa1f]
    > /lib/libc.so.6(+0x7a460)[0x7f8176f52460]
    > /lib/libc.so.6(cfree+0x73)[0x7f8176f55e53]
    > ./multSim[0x40bba6]
    > ./multSim[0x4128f6]
    > ./multSim[0x412b86]
    > ./multSim[0x4089e9]
    > ./multSim[0x4140a7]
    > ./multSim[0x41362b]
    > ./multSim[0x411940]
    > /lib/libc.so.6(__libc_start_main+0xfd)[0x7f8176ef6c4d]
    > ./multSim[0x4032c9]
    > ======= Memory map: ========
    > 00400000-0041c000 r-xp 00000000 08:32 15991583
    > and similar lines....
    >
    > in such a situation, is there any generic approach for finding the
    > bug?


    I can give one more input so that the experts here may be able to give
    me some suggestions.
    My defintion of the pointer is like this:

    set<double> * distances; //inside the class as private element.

    //in the constructor
    distances = new set<double>;

    //in the destructor
    delete distances;

    what i found is, if I dont delete the distances variable in the
    destructor, I am fine....

    any suggestions?

    thanks
    suresh
    suresh, Sep 11, 2010
    #6
  7. * suresh, on 11.09.2010 05:05:
    > On Sep 10, 7:59 pm, suresh<> wrote:
    >> On Sep 10, 6:50 pm, "Alf P. Steinbach /Usenet"<alf.p.steinbach
    >>
    >> > wrote:
    >>> * suresh, on 11.09.2010 03:43:

    >>
    >>>> what is setd::set? Or you meant std::set?
    >>>> suresh

    >>
    >>> Yes, my keyboard gremlin got a little too much water.

    >>
    >> I am unable to reproduce the error in a smaller code bcz it works
    >> fine...but in my main code, it says
    >>
    >> *** glibc detected *** ./multSim: corrupted double-linked list:
    >> 0x00000000011cb030 ***
    >> ======= Backtrace: =========
    >> /lib/libc.so.6(+0x775b6)[0x7f8176f4f5b6]
    >> /lib/libc.so.6(+0x77a1f)[0x7f8176f4fa1f]
    >> /lib/libc.so.6(+0x7a460)[0x7f8176f52460]
    >> /lib/libc.so.6(cfree+0x73)[0x7f8176f55e53]
    >> ./multSim[0x40bba6]
    >> ./multSim[0x4128f6]
    >> ./multSim[0x412b86]
    >> ./multSim[0x4089e9]
    >> ./multSim[0x4140a7]
    >> ./multSim[0x41362b]
    >> ./multSim[0x411940]
    >> /lib/libc.so.6(__libc_start_main+0xfd)[0x7f8176ef6c4d]
    >> ./multSim[0x4032c9]
    >> ======= Memory map: ========
    >> 00400000-0041c000 r-xp 00000000 08:32 15991583
    >> and similar lines....
    >>
    >> in such a situation, is there any generic approach for finding the
    >> bug?

    >
    > I can give one more input so that the experts here may be able to give
    > me some suggestions.
    > My defintion of the pointer is like this:
    >
    > set<double> * distances; //inside the class as private element.
    >
    > //in the constructor
    > distances = new set<double>;
    >
    > //in the destructor
    > delete distances;
    >
    > what i found is, if I dont delete the distances variable in the
    > destructor, I am fine....
    >
    > any suggestions?


    Yes, same as before:

    "Try again with the pointer but set it to point at a std::set variable at the
    call site."



    Cheers & hth.,

    - Alf

    --
    blog at <url: http://alfps.wordpress.com>
    Alf P. Steinbach /Usenet, Sep 11, 2010
    #7
  8. suresh

    suresh Guest

    On Sep 10, 8:05 pm, suresh <> wrote:
    > On Sep 10, 7:59 pm, suresh <> wrote:
    >
    >
    >
    >
    >
    > > On Sep 10, 6:50 pm, "Alf P. Steinbach /Usenet" <alf.p.steinbach

    >
    > > > wrote:
    > > > * suresh, on 11.09.2010 03:43:

    >
    > > > > what is setd::set? Or  you meant std::set?
    > > > > suresh

    >
    > > > Yes, my keyboard gremlin got a little too much water.

    >
    > > I am unable to reproduce the error in a smaller code bcz it works
    > > fine...but in my main code, it says

    >
    > > *** glibc detected *** ./multSim: corrupted double-linked list:
    > > 0x00000000011cb030 ***
    > > ======= Backtrace: =========
    > > /lib/libc.so.6(+0x775b6)[0x7f8176f4f5b6]
    > > /lib/libc.so.6(+0x77a1f)[0x7f8176f4fa1f]
    > > /lib/libc.so.6(+0x7a460)[0x7f8176f52460]
    > > /lib/libc.so.6(cfree+0x73)[0x7f8176f55e53]
    > > ./multSim[0x40bba6]
    > > ./multSim[0x4128f6]
    > > ./multSim[0x412b86]
    > > ./multSim[0x4089e9]
    > > ./multSim[0x4140a7]
    > > ./multSim[0x41362b]
    > > ./multSim[0x411940]
    > > /lib/libc.so.6(__libc_start_main+0xfd)[0x7f8176ef6c4d]
    > > ./multSim[0x4032c9]
    > > ======= Memory map: ========
    > > 00400000-0041c000 r-xp 00000000 08:32 15991583
    > > and similar lines....

    >
    > > in such a situation, is there any generic approach for finding the
    > > bug?

    >
    > I can give one more input so that the experts here may be able to give
    > me some suggestions.
    > My defintion of the pointer is like this:
    >
    > set<double> * distances; //inside the class as private element.
    >
    > //in the constructor
    > distances = new set<double>;
    >
    > //in the destructor
    > delete distances;
    >
    > what i found is, if I dont delete the distances variable in the
    > destructor, I am fine....
    >
    > any suggestions?


    I have realised that its an issue of deleting a pointer twice. Hence I
    have made a new post with different title to make this issue more
    clearer to the experts.

    Thanks
    suresh
    suresh, Sep 11, 2010
    #8
  9. suresh

    suresh Guest

    On Sep 10, 8:29 pm, "Alf P. Steinbach /Usenet" <alf.p.steinbach
    > wrote:
    > * suresh, on 11.09.2010 05:05:
    >
    >
    >
    >
    >
    > > On Sep 10, 7:59 pm, suresh<>  wrote:
    > >> On Sep 10, 6:50 pm, "Alf P. Steinbach /Usenet"<alf.p.steinbach

    >
    > >> >  wrote:
    > >>> * suresh, on 11.09.2010 03:43:

    >
    > >>>> what is setd::set? Or  you meant std::set?
    > >>>> suresh

    >
    > >>> Yes, my keyboard gremlin got a little too much water.

    >
    > >> I am unable to reproduce the error in a smaller code bcz it works
    > >> fine...but in my main code, it says

    >
    > >> *** glibc detected *** ./multSim: corrupted double-linked list:
    > >> 0x00000000011cb030 ***
    > >> ======= Backtrace: =========
    > >> /lib/libc.so.6(+0x775b6)[0x7f8176f4f5b6]
    > >> /lib/libc.so.6(+0x77a1f)[0x7f8176f4fa1f]
    > >> /lib/libc.so.6(+0x7a460)[0x7f8176f52460]
    > >> /lib/libc.so.6(cfree+0x73)[0x7f8176f55e53]
    > >> ./multSim[0x40bba6]
    > >> ./multSim[0x4128f6]
    > >> ./multSim[0x412b86]
    > >> ./multSim[0x4089e9]
    > >> ./multSim[0x4140a7]
    > >> ./multSim[0x41362b]
    > >> ./multSim[0x411940]
    > >> /lib/libc.so.6(__libc_start_main+0xfd)[0x7f8176ef6c4d]
    > >> ./multSim[0x4032c9]
    > >> ======= Memory map: ========
    > >> 00400000-0041c000 r-xp 00000000 08:32 15991583
    > >> and similar lines....

    >
    > >> in such a situation, is there any generic approach for finding the
    > >> bug?

    >
    > > I can give one more input so that the experts here may be able to give
    > > me some suggestions.
    > > My defintion of the pointer is like this:

    >
    > > set<double>  * distances; //inside the class as private element.

    >
    > > //in the constructor
    > > distances = new set<double>;

    >
    > > //in the destructor
    > > delete distances;

    >
    > > what i found is, if I dont delete the distances variable in the
    > > destructor, I am fine....

    >
    > > any suggestions?

    >
    > Yes, same as before:
    >
    > "Try again with the pointer but set it to point at a std::set variable at the
    > call site."


    what do you mean by "call site"?
    suresh
    suresh, Sep 11, 2010
    #9
  10. suresh

    James Kanze Guest

    On Sep 11, 4:05 am, suresh <> wrote:
    > On Sep 10, 7:59 pm, suresh <> wrote:


    [...]
    > I can give one more input so that the experts here may be able to give
    > me some suggestions.
    > My defintion of the pointer is like this:


    > set<double> * distances; //inside the class as private element.


    How and when does it get set? How is it copied?

    > //in the constructor
    > distances = new set<double>;


    In which constructor: all of them (including the copy
    constructor), or?

    > //in the destructor
    > delete distances;


    Under what conditions?

    > what i found is, if I dont delete the distances variable in
    > the destructor, I am fine....


    > any suggestions?


    A quick fix (and possibly the best solution in this case,
    although we don't have enough information to be sure) would be
    to use boost::shared_ptr<std::set<double> >, rather than a raw
    pointer. Still, I would suggest you start by learning about the
    rule of four: try reading Scott Meyers' _Effective_ _C++_, for
    starters.

    --
    James Kanze
    James Kanze, Sep 11, 2010
    #10
  11. On 11 sep, 03:24, suresh <> wrote:
    > Hi,
    > In my code, the operator() method of a function object  is designed to
    > fill a set which is a private data member of the function object. This
    > function object is used in min_element algorithm.
    > Since the min_element algorithm uses a copy of the function object (as
    > per my understanding - hoping it to be true), I am unable to access
    > the set data member of the function object.  A minimal code is show
    > below:
    >
    > class FO{
    > public:
    > bool operator()(int a, int b);
    > private:
    > set<int> s;};
    >
    > bool FO::eek:perator()(int a,int b){
    > s.insert(a);
    > return (a<b);}
    >
    > vector<int> v;
    > //vector populated
    > FO fo;
    > min_element(v.begin(),v.end(),fo);
    >
    > Only after some time I realised that min_element takes only a copy of
    > the variable fo. [I found that the size of the set is always zero
    > after the call to  min_element]. As a solution to this problem, I
    > tried to define the variable s as a pointer to set (set<int> *s) and
    > then modified the code accordingly but when the code is running, half
    > way thru, the code aborts saying  corrupted double-linked list:
    > 0x000000000102beb0 ***.
    >
    > What is the solution to this issue?


    My crystal ball suggests that you delete 's' member in the destructor
    causing it to be corrupted in copies of fo.

    Try something like:

    class FO{
    public:
    FO( set<int>& is):s(&is){}

    bool operator()(int a, int b);

    private:
    set<int>* s;
    };

    bool FO::eek:perator()(int a,int b){
    s->insert(a);
    return (a<b);
    }

    set<int> fo;
    min_element(v.begin(),v.end(),FO(fo));

    --
    Michael
    Michael Doubez, Sep 13, 2010
    #11
  12. On 13 sep, 15:41, Michael Doubez <> wrote:
    > On 11 sep, 03:24, suresh <> wrote:
    >
    >
    >
    > > Hi,
    > > In my code, the operator() method of a function object  is designed to
    > > fill a set which is a private data member of the function object. This
    > > function object is used in min_element algorithm.
    > > Since the min_element algorithm uses a copy of the function object (as
    > > per my understanding - hoping it to be true), I am unable to access
    > > the set data member of the function object.  A minimal code is show
    > > below:

    >
    > > class FO{
    > > public:
    > > bool operator()(int a, int b);
    > > private:
    > > set<int> s;};

    >
    > > bool FO::eek:perator()(int a,int b){
    > > s.insert(a);
    > > return (a<b);}

    >
    > > vector<int> v;
    > > //vector populated
    > > FO fo;
    > > min_element(v.begin(),v.end(),fo);

    >
    > > Only after some time I realised that min_element takes only a copy of
    > > the variable fo. [I found that the size of the set is always zero
    > > after the call to  min_element]. As a solution to this problem, I
    > > tried to define the variable s as a pointer to set (set<int> *s) and
    > > then modified the code accordingly but when the code is running, half
    > > way thru, the code aborts saying  corrupted double-linked list:
    > > 0x000000000102beb0 ***.

    >
    > > What is the solution to this issue?

    >
    > My crystal ball suggests that you delete 's' member in the destructor
    > causing it to be corrupted in copies of fo.


    Oups. It didn't extend to showing me you had solved the problem.
    sorry for the noise.

    --
    Michael
    Michael Doubez, Sep 13, 2010
    #12
  13. suresh

    suresh Guest

    On Sep 11, 11:01 am, James Kanze <> wrote:
    > On Sep 11, 4:05 am, suresh <> wrote:
    >
    > > On Sep 10, 7:59 pm, suresh <> wrote:

    >
    >    [...]
    >
    > > I can give one more input so that the experts here may be able to give
    > > me some suggestions.
    > > My defintion of the pointer is like this:
    > > set<double> * distances; //inside the class as private element.

    >
    > How and when does it get set?  How is it copied?


    It is set in the constructor as shown below.
    >
    > > //in the constructor
    > > distances = new set<double>;

    >
    > In which constructor: all of them (including the copy
    > constructor), or?


    I have not written a copy constructor. So the compilers default copy
    constructor is used.
    >
    > > //in the destructor
    > > delete distances;

    >
    > Under what conditions?

    What I meant is, when the code was aborted during execution, I was
    trying to see what triggers abort and I found that removing delete
    distances removes abort. But then it would result in non freeing of
    memory and I didnt want to use that "crude" solution to my problem.
    However I realised that it happens because the pointer is deleted
    twice. Once when the copied object is destructed at the end of
    execution of min_element algorithm and once when my own destructor is
    called.

    >
    > > what i found is, if I dont delete the distances variable in
    > > the destructor, I am fine....
    > > any suggestions?

    >
    > A quick fix (and possibly the best solution in this case,
    > although we don't have enough information to be sure) would be
    > to use boost::shared_ptr<std::set<double> >, rather than a raw
    > pointer.  Still, I would suggest you start by learning about the
    > rule of four: try reading Scott Meyers' _Effective_ _C++_, for
    > starters.


    I think boost::shared_ptr is the solution to my problem. Will look at
    Scott Meyers' _Effective_ _C++_ too.
    thanks
    suresh
    suresh, Sep 13, 2010
    #13
  14. suresh

    suresh Guest

    On Sep 13, 6:41 am, Michael Doubez <> wrote:
    > On 11 sep, 03:24, suresh <> wrote:
    >
    >
    >
    >
    >
    > > Hi,
    > > In my code, the operator() method of a function object  is designed to
    > > fill a set which is a private data member of the function object. This
    > > function object is used in min_element algorithm.
    > > Since the min_element algorithm uses a copy of the function object (as
    > > per my understanding - hoping it to be true), I am unable to access
    > > the set data member of the function object.  A minimal code is show
    > > below:

    >
    > > class FO{
    > > public:
    > > bool operator()(int a, int b);
    > > private:
    > > set<int> s;};

    >
    > > bool FO::eek:perator()(int a,int b){
    > > s.insert(a);
    > > return (a<b);}

    >
    > > vector<int> v;
    > > //vector populated
    > > FO fo;
    > > min_element(v.begin(),v.end(),fo);

    >
    > > Only after some time I realised that min_element takes only a copy of
    > > the variable fo. [I found that the size of the set is always zero
    > > after the call to  min_element]. As a solution to this problem, I
    > > tried to define the variable s as a pointer to set (set<int> *s) and
    > > then modified the code accordingly but when the code is running, half
    > > way thru, the code aborts saying  corrupted double-linked list:
    > > 0x000000000102beb0 ***.

    >
    > > What is the solution to this issue?

    >
    > My crystal ball suggests that you delete 's' member in the destructor
    > causing it to be corrupted in copies of fo.
    >
    > Try something like:
    >
    > class FO{
    > public:
    > FO( set<int>& is):s(&is){}
    >
    > bool operator()(int a, int b);
    >
    > private:
    > set<int>* s;
    >
    > };
    >
    > bool FO::eek:perator()(int a,int b){
    > s->insert(a);
    > return (a<b);
    >
    > }
    >
    > set<int> fo;
    > min_element(v.begin(),v.end(),FO(fo));

    thanks Micheal, I had tried this solution and it worked but I was
    looking for a different solution.
    thanks again
    suresh
    suresh, Sep 13, 2010
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ahmed Moustafa
    Replies:
    0
    Views:
    764
    Ahmed Moustafa
    Nov 15, 2003
  2. Bapaiah Katepalli
    Replies:
    1
    Views:
    1,481
    Mike Treseler
    Jun 23, 2006
  3. bb
    Replies:
    5
    Views:
    349
    Pete Becker
    May 9, 2006
  4. , India
    Replies:
    1
    Views:
    662
    Pascal J. Bourguignon
    Apr 22, 2008
  5. Sparhawk
    Replies:
    5
    Views:
    107
    Harag
    Aug 29, 2004
Loading...

Share This Page