boost shared pointer

Jun 29, 2013 at 11:34am
I am trying to learn shared pointers
the code as is works fine.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <vector>
#include <set>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <boost/shared_ptr.hpp>
#include <fstream>

struct Foo
{ 
  Foo( std::ofstream &_x ) : file(_x) {}
  std::ofstream &file;
};

typedef boost::shared_ptr<Foo> FooPtr;

int main()
{
	std::ofstream myfile1("hello1.csv");
	std::ofstream myfile2("hello2.csv");
	std::ofstream myfile3("hello3.csv");
	std::ofstream myfile4("hello4.csv");

	std::vector<FooPtr>  foo_vector;
	 
	FooPtr foo_ptr( new Foo(myfile1));
	foo_vector.push_back( foo_ptr );

	foo_ptr.reset( new Foo(myfile2));
	foo_vector.push_back( foo_ptr );

	foo_ptr.reset( new Foo(myfile3));
	foo_vector.push_back( foo_ptr );

	foo_ptr.reset( new Foo(myfile4));
	foo_vector.push_back( foo_ptr );

	for (int i=0; i < foo_vector.size(); i++)
	{
		foo_vector[1]->file << "Hello" << i << std::endl;
	}  

  int x;
  std::cin >> x;
  return 0;
}


i want to create my files dynamically when i try it this way. i don't get compile errors but my program crashes. could you please point out what i am doing wrong.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <vector>
#include <set>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <boost/shared_ptr.hpp>
#include <fstream>

struct Foo
{ 
  Foo( std::ofstream &_x ) : file(_x) {}
  std::ofstream &file;
};

typedef boost::shared_ptr<Foo> FooPtr;

FooPtr foo_ptr;

int main()
{
	std::vector<FooPtr>  foo_vector;

	for( int i = 0; i < 4; i++)
	{
		std::stringstream temp;
		temp << "hello" << i << ".csv";
		foo_ptr.reset( new Foo(std::ofstream(temp.str().c_str())));
		foo_vector.push_back( foo_ptr );
	}

	for (int i=0; i < foo_vector.size(); i++)
	{
		foo_vector[1]->file << "Hello" << i << std::endl;
	}  

  int x;
  std::cin >> x;
  return 0;
}



Jun 29, 2013 at 12:21pm
std::ofstream(temp.str().c_str()) is an r-value.
Last edited on Jun 29, 2013 at 12:52pm
Jun 29, 2013 at 12:53pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <vector>
#include <set>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <boost/shared_ptr.hpp>
#include <fstream>

struct Foo
{ 
  Foo( std::ofstream *_x ) : file(_x) {}
  std::ofstream *file;
};

typedef boost::shared_ptr<Foo> FooPtr;

FooPtr foo_ptr;
int main()
{
	std::vector<FooPtr>  foo_vector;

	for( int i = 0; i < 4; i++)
	{
		std::stringstream temp;
		temp << "hello" << i << ".csv";
		std::ofstream *o = new std::ofstream(temp.str().c_str());
		foo_ptr.reset( new Foo(o));
		foo_vector.push_back( foo_ptr );
	}

	for (int i=0; i < foo_vector.size(); i++)
	{
		*foo_vector[1]->file << "Hello" << i << std::endl;
	}  

  int x;
  std::cin >> x;
  return 0;
}


i did this and it now works am i using shared pointers correctly?
Jun 29, 2013 at 1:05pm
The vector holds copies of FooPtr, so it is fine as far as Foo is concerned.
However, we need to also take care of the dynamically allocated std::ofstream objects.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
struct Foo
{
  Foo( boost::shared_ptr<std::ofstream> _x ) : file(_x) {}
  boost::shared_ptr<std::ofstream> file;
};

typedef boost::shared_ptr<Foo> FooPtr;

FooPtr foo_ptr ;

int main()
{
    std::vector<FooPtr>  foo_vector;

    // ...

    boost::shared_ptr<std::ofstream> o( new std::ofstream(temp.str().c_str()) );
    foo_ptr.reset( new Foo(o) );
    foo_vector.push_back( foo_ptr );

    // ...

}
Jun 29, 2013 at 1:08pm
Looks OK to me.

On line 26 you create a shared pointer to the dynamically-allocated ofstream object.

On line 28, you push the shared pointer onto foo_vector, which creates a copy of it, which means that there are now two shared pointers to the ofstream.

At the end of that iteration of the for loop, the first shared pointer falls out of scope, but the one in the vector still exists and still points to the ofstream, so the ofstream is not destroyed.

At the end of the main function, foo_vector falls out of scope, so the final remaining shared pointer to the ofstream is destroyed, so it destroys the ofstream that it's pointing to.

Thus the memory for ofstream is freed only when the last shared pointer to it is destroyed.

The above is true for each ofstream object that you dynamically create in your first for loop.
Last edited on Jun 29, 2013 at 1:09pm
Topic archived. No new replies allowed.