STL problem

T

Tony Johansson

Hello!

I have some problem with STL.

I have two classes called Handle which is a template class and Integer which
is not a template class. The Integer class is just a wrapper class for a
primitive int with some methods. I don't show the Integer class because it
will not add any information to my problem. Main is using some STL function

Now to my problem.
If I do this sequence in main first create two Handle object myh1 and myh2.
Then I use push_front to first push in myh1 and then myh2.
Then I use the STL function for_each in this way
for_each(myList1.begin(), myList1.end(), writeOut);
This function for_each will write out the entire list by calling the global
function writeOut for each handle object in the
list. So in this case will this writeOut write 2 and then 1 which is
correct.
This function writeOut looks like
void writeOut(handle_t& h)
{ cout << *h.body;}

But now to the strange thing if I use for_each with the functionoperator in
this way instead.
for_each(myList1.begin(), myList1.end(), handle_t() );
The function operator looks like. The last parameter is calling the function
operator for each Handle in the list.
void operator()(Handle& temp)
{ cout << *temp.body; }
This function operator will be called for each handle object in the list.

When this for_each is executing is first 2 written and then 1 and then the
program krasch with this error message

An unhandled exception of type 'System.NullReferenceException' occurred in
lab4_c++.exe
Additional information: Object reference not set to an instance of an
object.

I can't understand why the program krasch when I use a function operator.

Have you any suggestion ?

//Tony

#include "handle.h"
#include <list>
#include <algorithm>
using namespace std;

typedef Handle<Integer> handle_t;

void skrivUt(handle_t& h)
{ cout << *h.body;}

main()
{
list<handle_t> myList1;
handle_t myh1( new Integer(1) );
handle_t myh2( new Integer(2) );

myList1.push_front(myh1);
myList1.push_front(myh2);

for_each(myList1.begin(), myList1.end(), writeOut); //This works fine
for_each(myList1.begin(), myList1.end(), handle_t()); //This statement
will krasch the application
}

#include "integer.h"
#include <iostream>
using namespace std;

template<class T>
class Handle
{
public:
Handle() {}

Handle(T* body_ptr) //Constructor
{
body = body_ptr;
ref_count = new int(1);
}

bool operator==(const Handle& temp)
{ return *body == *temp.body; }

Handle(const Handle& h) //Copy constructor
{
body = h.body;
ref_count = h.ref_count;
(*ref_count)++;
}

void operator()(Handle& temp) //Functionoperator
{ cout << temp.body << endl; }
private:
T* body;
int* ref_count;
};
 
A

Andre Kostur

Hello!

I have some problem with STL.

I have two classes called Handle which is a template class and Integer
which is not a template class. The Integer class is just a wrapper
class for a primitive int with some methods. I don't show the Integer
class because it will not add any information to my problem. Main is
using some STL function

Now to my problem.
If I do this sequence in main first create two Handle object myh1 and
myh2. Then I use push_front to first push in myh1 and then myh2.
Then I use the STL function for_each in this way
for_each(myList1.begin(), myList1.end(), writeOut);
This function for_each will write out the entire list by calling the
global function writeOut for each handle object in the
list. So in this case will this writeOut write 2 and then 1 which is
correct.
This function writeOut looks like
void writeOut(handle_t& h)
{ cout << *h.body;}

But now to the strange thing if I use for_each with the
functionoperator in this way instead.
for_each(myList1.begin(), myList1.end(), handle_t() );
The function operator looks like. The last parameter is calling the
function operator for each Handle in the list.
void operator()(Handle& temp)
{ cout << *temp.body; }
This function operator will be called for each handle object in the
list.

When this for_each is executing is first 2 written and then 1 and then
the program krasch with this error message

An unhandled exception of type 'System.NullReferenceException'
occurred in lab4_c++.exe
Additional information: Object reference not set to an instance of an
object.

I can't understand why the program krasch when I use a function
operator.

Have you any suggestion ?

//Tony

#include "handle.h"
#include <list>
#include <algorithm>
using namespace std;

typedef Handle<Integer> handle_t;

void skrivUt(handle_t& h)
{ cout << *h.body;}

I'm assuming this is your "writeOut" function...

That should be:

int main()
{
list<handle_t> myList1;
handle_t myh1( new Integer(1) );
handle_t myh2( new Integer(2) );

myList1.push_front(myh1);
myList1.push_front(myh2);

for_each(myList1.begin(), myList1.end(), writeOut); //This works
fine for_each(myList1.begin(), myList1.end(), handle_t()); //This
statement
will krasch the application
}

#include "integer.h"
#include <iostream>
using namespace std;

template<class T>
class Handle
{
public:
Handle() {}

Handle(T* body_ptr) //Constructor
{
body = body_ptr;
ref_count = new int(1);
}

bool operator==(const Handle& temp)
{ return *body == *temp.body; }

Handle(const Handle& h) //Copy constructor
{
body = h.body;
ref_count = h.ref_count;
(*ref_count)++;
}

void operator()(Handle& temp) //Functionoperator
{ cout << temp.body << endl; }

Shouldn't this line be:

{ cout << temp->body << endl; }

?
 
K

Kai-Uwe Bux

Tony Johansson wrote:

[snip]
#include "handle.h"
#include <list>
#include <algorithm>
using namespace std;

typedef Handle<Integer> handle_t;

void skrivUt(handle_t& h)
{ cout << *h.body;}

main()

You mean:

int main()
{
list<handle_t> myList1;
handle_t myh1( new Integer(1) );
handle_t myh2( new Integer(2) );

myList1.push_front(myh1);
myList1.push_front(myh2);

for_each(myList1.begin(), myList1.end(), writeOut); //This works
fine
for_each(myList1.begin(), myList1.end(), handle_t()); //This statement
will krasch the application
}

#include "integer.h"
#include <iostream>
using namespace std;

Is this part of the file "handle.h"? If so: it is considerted a Bad
Idea(tm) to import std in header files.
template<class T>
class Handle
{
public:
Handle() {}

Handle(T* body_ptr) //Constructor
{
body = body_ptr;
ref_count = new int(1);
}

bool operator==(const Handle& temp)
{ return *body == *temp.body; }

Handle(const Handle& h) //Copy constructor
{
body = h.body;
ref_count = h.ref_count;
(*ref_count)++;
}

void operator()(Handle& temp) //Functionoperator
{ cout << temp.body << endl; }

Do you really want to write the pointer to cout, or do you mean the
pointee, i.e., should this be:

{ cout << *temp.body << endl; }
private:
T* body;
int* ref_count;
};

Your class has pointer members but lacks a destructor. It will leak memory.
Also, if you have a destructor that you did not post, it might very well be
the source of the segfault. The temporary that you are passing to for_each
can get copied and destructed.


Best

Kai-Uwe Bux
 
K

Kai-Uwe Bux

Just one more thing:

Kai-Uwe Bux said:
Tony Johansson wrote:

[snip]
template<class T>
class Handle
{
public:
Handle() {}

Handle(T* body_ptr) //Constructor
{
body = body_ptr;
ref_count = new int(1);
}

bool operator==(const Handle& temp)
{ return *body == *temp.body; }

Handle(const Handle& h) //Copy constructor
{
body = h.body;
ref_count = h.ref_count;
(*ref_count)++;
}

This copy constructor will not work on objects constructed by Handle<T>():
Note that Handle<T>() sets body and ref_count to 0 (or leaves them
uninitialized, which would be as bad). In the copy constructor, the pointer
ref_count is dereferenced. If it was not initialized to actually point to
an int, you have undefined behavior.


Best

Kai-Uwe Bux
 

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

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top