boost shared pointer

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;
}



std::ofstream(temp.str().c_str()) is an r-value.
Last edited on
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?
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 );

    // ...

}
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
Topic archived. No new replies allowed.