min_element algorithm and function object copying

S

suresh

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
 
A

Alf P. Steinbach /Usenet

* 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
 
S

suresh

* 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
 
A

Alf P. Steinbach /Usenet

* 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
 
S

suresh

* suresh, on 11.09.2010 03:43:




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
 
S

suresh

* suresh, on 11.09.2010 03:43:
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
 
A

Alf P. Steinbach /Usenet

* suresh, on 11.09.2010 05:05:
* 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
 
S

suresh

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
 
S

suresh

* suresh, on 11.09.2010 05:05:




On Sep 10, 6:50 pm, "Alf P. Steinbach /Usenet"<alf.p.steinbach
(e-mail address removed)>  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
 
J

James Kanze

On Sep 10, 7:59 pm, suresh <[email protected]> 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.
 
M

Michael Doubez

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));
 
M

Michael Doubez

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.
 
S

suresh

On Sep 10, 7:59 pm, suresh <[email protected]> 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 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.
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.
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
 
S

suresh

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top