1 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2 // test_delete_pointer.cpp
3
4 // (C) Copyright 2002 Vahan Margaryan.
5 // Use, modification and distribution is subject to the Boost Software
6 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8 //
9
10 #include <cstddef> // NULL
11 #include <fstream>
12
13 #include <cstdio> // remove
14 #include <boost/config.hpp>
15 #if defined(BOOST_NO_STDC_NAMESPACE)
16 namespace std{
17 using ::remove;
18 }
19 #endif
20
21 #include "test_tools.hpp"
22 #include <boost/core/no_exceptions_support.hpp>
23 #include <boost/serialization/throw_exception.hpp>
24
25 #include <boost/serialization/nvp.hpp>
26 #include <boost/serialization/split_member.hpp>
27
28 //A holds a pointer to another A, but doesn't own the pointer.
29 //objCount
30 class A
31 {
32 friend class boost::serialization::access;
33 template<class Archive>
save(Archive & ar,const unsigned int) const34 void save(Archive &ar, const unsigned int /* file_version */) const
35 {
36 ar << BOOST_SERIALIZATION_NVP(next_);
37 }
38 template<class Archive>
load(Archive & ar,const unsigned int)39 void load(Archive & ar, const unsigned int /* file_version */)
40 {
41 ar >> BOOST_SERIALIZATION_NVP(next_);
42 ++loadcount;
43 }
44 BOOST_SERIALIZATION_SPLIT_MEMBER()
45 public:
A()46 A()
47 {
48 if(test && objcount == 3)
49 boost::serialization::throw_exception(boost::archive::archive_exception(
50 boost::archive::archive_exception::no_exception
51 ));
52 next_ = 0;
53 ++objcount;
54 }
~A()55 ~A(){
56 delete next_;
57 --objcount;
58 }
59 A* next_;
60 static int objcount;
61 static bool test;
62 static int loadcount;
63 };
64
65
66 int A::objcount = 0;
67 int A::loadcount = 0;
68 bool A::test = false;
69
70 int
test_main(int,char * [])71 test_main( int /* argc */, char* /* argv */[] )
72 {
73
74 //fill the vector with chained A's. The vector is assumed
75 //to own the objects - we will destroy the objects through this vector.
76
77 A * head = new A;
78 A* last = head;
79 unsigned int i;
80 for(i = 1; i < 9; ++i)
81 {
82 A *a = new A;
83 last->next_ = a;
84 last = a;
85 }
86
87 const char * testfile = boost::archive::tmpnam(0);
88 BOOST_REQUIRE(NULL != testfile);
89
90 //output the list
91 {
92 test_ostream os(testfile, TEST_STREAM_FLAGS);
93 test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
94 oa << BOOST_SERIALIZATION_NVP(head);
95 }
96
97 delete head;
98 BOOST_CHECK(A::objcount == 0);
99
100 head = NULL;
101 A::test = true;
102 //read the list back
103 {
104 test_istream is(testfile, TEST_STREAM_FLAGS);
105 test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
106 BOOST_TRY {
107 ia >> BOOST_SERIALIZATION_NVP(head);
108 }
109 BOOST_CATCH (...){
110 ia.delete_created_pointers();
111 }
112 BOOST_CATCH_END
113 }
114
115 //identify the leaks
116 BOOST_CHECK(A::loadcount == 0);
117 std::remove(testfile);
118 return EXIT_SUCCESS;
119 }
120