Skip to content

Commit 41a0901

Browse files
committed
Resurrect ref counting code. Fixes crash, but test still fails
1 parent ca8d4c0 commit 41a0901

File tree

4 files changed

+182
-29
lines changed

4 files changed

+182
-29
lines changed

src/Core/Matlab/matfiledata.cc

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,26 +60,80 @@
6060
using namespace SCIRun::MatlabIO;
6161

6262
matfiledata::matfiledata()
63-
: m_(0), ptr_(0)
63+
: m_(0), ptr_(0)
6464
{
65-
m_.reset(new mxdata);
65+
m_ = new mxdata;
66+
m_->dataptr_ = 0;
67+
m_->owndata_ = false;
68+
m_->bytesize_ = 0;
69+
m_->type_ = miUNKNOWN;
70+
m_->ref_ = 1;
6671
}
67-
72+
6873
matfiledata::matfiledata(matfiledata::mitype type)
69-
: m_(0) , ptr_(0)
74+
: m_(0) , ptr_(0)
7075
{
71-
m_.reset(new mxdata);
76+
m_ = new mxdata;
77+
m_->dataptr_ = 0;
78+
m_->owndata_ = false;
79+
m_->bytesize_ = 0;
7280
m_->type_ = type;
81+
m_->ref_ = 1;
82+
}
83+
84+
matfiledata::~matfiledata()
85+
{
86+
if (m_ != 0)
87+
{
88+
clearptr();
89+
}
7390
}
74-
91+
7592
void matfiledata::clear()
7693
{
7794
if (m_ == 0)
7895
{
7996
std::cerr << "internal error in clear()\n";
8097
throw internal_error();
8198
}
82-
m_.reset(new mxdata);
99+
if ((m_->dataptr_ != 0)&&(m_->owndata_ == true)) delete[] static_cast<char *>(m_->dataptr_);
100+
m_->owndata_ = false;
101+
m_->dataptr_ = 0;
102+
m_->bytesize_ = 0;
103+
m_->type_ = miUNKNOWN;
104+
}
105+
106+
void matfiledata::clearptr()
107+
{
108+
if (m_ == 0) return;
109+
m_->ref_--;
110+
if (m_->ref_ == 0)
111+
{
112+
clear();
113+
delete m_;
114+
}
115+
m_ = 0;
116+
ptr_ = 0;
117+
}
118+
119+
matfiledata::matfiledata(const matfiledata &mfd)
120+
{
121+
m_ = 0;
122+
m_ = mfd.m_;
123+
ptr_ = mfd.ptr_;
124+
m_->ref_++;
125+
}
126+
127+
matfiledata& matfiledata::operator= (const matfiledata &mfd)
128+
{
129+
if (this != &mfd)
130+
{
131+
clearptr();
132+
m_ = mfd.m_;
133+
ptr_ = mfd.ptr_;
134+
m_->ref_++;
135+
}
136+
return *this;
83137
}
84138

85139
void matfiledata::newdatabuffer(int bytesize,mitype type)

src/Core/Matlab/matfiledata.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,27 +109,30 @@ namespace SCIRun
109109

110110
// structure definitions
111111
private:
112-
struct mxdata
112+
struct mxdata
113113
{
114-
mxdata() : dataptr_(0), owndata_(false), bytesize_(0), type_(miUNKNOWN) {}
115-
//TODO DAN: fix this bad warning
116-
~mxdata() { if (owndata_) delete[] dataptr_; }
117114
void *dataptr_; // Store the data to put in the matfile
118115
bool owndata_; // Do we own the data
119116
int bytesize_; // Size of the data in bytes
120117
mitype type_; // The type of the data
121-
};
118+
int ref_; // reference counter
119+
};
122120

123121
// data objects
124-
private:
125-
boost::shared_ptr<mxdata> m_;
122+
mxdata *m_;
126123
void *ptr_;
124+
void clearptr();
127125

128-
// functions
126+
// functions
129127
public:
130128
matfiledata();
129+
~matfiledata();
130+
131131
explicit matfiledata(mitype type);
132132

133+
matfiledata(const matfiledata &m); // copy constructor
134+
matfiledata& operator= (const matfiledata &m); // assignment
135+
133136
// clear() will remove any databuffer and empty the object
134137
// After calling this function a new buffer can be created
135138
void clear();

src/Core/Matlab/matlabarray.cc

Lines changed: 93 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,70 @@
4444

4545
using namespace SCIRun::MatlabIO;
4646

47+
48+
// matlabarray management functions
49+
// constructor/destructor
50+
// assignment/copy constructor
51+
// clear
52+
53+
// constructor
54+
// creates on the place holder for the matlabarray
55+
matlabarray::matlabarray()
56+
: m_(0)
57+
{
58+
}
59+
60+
// destructor
61+
matlabarray::~matlabarray()
62+
{
63+
if (m_ != 0)
64+
{ // delete the attached structure if necessary
65+
m_->ref_--;
66+
if (m_->ref_ == 0) { delete m_; }
67+
m_ = 0;
68+
}
69+
}
70+
71+
// copy constructor
72+
matlabarray::matlabarray(const matlabarray &m)
73+
{
74+
m_ = 0;
75+
76+
// reference the same structure as the matlabarray we are copying
77+
if (m.m_ != 0)
78+
{
79+
m_ = m.m_;
80+
m_->ref_++;
81+
}
82+
}
83+
84+
85+
86+
// assignment
87+
matlabarray& matlabarray::operator= (const matlabarray &m)
88+
{ // the same construction as the previous function is used
89+
// to create a copy
90+
91+
// if m = m we have to do nothing
92+
if (this != &m)
93+
{
94+
if (m_ != 0)
95+
{ // delete the attached structure if necessary
96+
m_->ref_--;
97+
if (m_->ref_ == 0) { delete m_; }
98+
m_ = 0;
99+
}
100+
101+
if (m.m_ != 0)
102+
{
103+
m_ = m.m_;
104+
m_->ref_++;
105+
}
106+
}
107+
108+
return *this;
109+
}
110+
47111
// clear and empty
48112

49113
// Clear: this function is for clearing the contents of the matrix and dereferencing
@@ -53,9 +117,16 @@ using namespace SCIRun::MatlabIO;
53117

54118
void matlabarray::clear()
55119
{
56-
m_.reset();
120+
121+
if (m_ != 0)
122+
{ // delete the attached structure if necessary
123+
124+
m_->ref_--;
125+
if (m_->ref_ == 0) { delete m_; }
126+
m_ = 0;
127+
}
57128
}
58-
129+
59130
// This function can be used to test whether the matrix contains any data
60131
// If not do not try to access the matrix components. This will result in
61132
// an internal_error exception
@@ -72,7 +143,8 @@ matlabarray matlabarray::clone() const
72143
matlabarray ma;
73144
if (isempty()) return(ma);
74145

75-
ma.m_.reset(new mxarray);
146+
ma.m_ = new mxarray;
147+
ma.m_->ref_ = 1;
76148
ma.m_->class_ = m_->class_;
77149
ma.m_->type_ = m_->type_;
78150
ma.m_->flags_ = m_->flags_;
@@ -689,7 +761,8 @@ void matlabarray::createdensearray(const std::vector<int> &dims,mitype type)
689761

690762
clear(); // make sure there is no data
691763

692-
m_.reset(new mxarray);
764+
m_ = new mxarray;
765+
m_->ref_ = 1;
693766

694767
m_->class_ = mlDENSE;
695768
m_->type_ = type;
@@ -707,7 +780,8 @@ void matlabarray::createdensearray(int m,int n,mitype type)
707780

708781
clear(); // make sure there is no data
709782

710-
m_.reset(new mxarray);
783+
m_ = new mxarray;
784+
m_->ref_ = 1;
711785

712786
m_->class_ = mlDENSE;
713787
m_->type_ = type;
@@ -722,7 +796,8 @@ void matlabarray::createsparsearray(const std::vector<int> &dims,mitype type)
722796
{
723797
clear(); // make sure there is no data
724798

725-
m_.reset(new mxarray);
799+
m_ = new mxarray;
800+
m_->ref_ = 1;
726801
m_->class_ = mlSPARSE;
727802
m_->type_ = type; // need to add some type checking here
728803
m_->flags_ = 0;
@@ -738,7 +813,8 @@ void matlabarray::createsparsearray(int m,int n,mitype type)
738813

739814
clear(); // make sure there is no data
740815

741-
m_.reset(new mxarray);
816+
m_ = new mxarray;
817+
m_->ref_ = 1;
742818
m_->class_ = mlSPARSE;
743819
m_->type_ = type; // need to add some type checking here
744820
m_->flags_ = 0;
@@ -753,7 +829,8 @@ void matlabarray::createcellarray(const std::vector<int> &dims)
753829
{
754830
clear(); // make sure there is no data
755831

756-
m_.reset(new mxarray);
832+
m_ = new mxarray;
833+
m_->ref_ = 1;
757834

758835
m_->class_ = mlCELL;
759836
m_->type_ = miMATRIX; // need to add some type checking here
@@ -777,7 +854,8 @@ void matlabarray::createstructarray(const std::vector<int> &dims, const std::vec
777854
{
778855
clear(); // make sure there is no data
779856

780-
m_.reset(new mxarray);
857+
m_ = new mxarray;
858+
m_->ref_ = 1;
781859
m_->class_ = mlSTRUCT;
782860
m_->type_ = miMATRIX; // need to add some type checking here
783861
m_->flags_ = 0;
@@ -792,7 +870,8 @@ void matlabarray::createstructarray()
792870
{
793871
clear(); // make sure there is no data
794872

795-
m_.reset(new mxarray);
873+
m_ = new mxarray;
874+
m_->ref_ = 1;
796875
m_->class_ = mlSTRUCT;
797876
m_->type_ = miMATRIX; // need to add some type checking here
798877
m_->flags_ = 0;
@@ -820,7 +899,8 @@ void matlabarray::createclassarray(const std::vector<int> &dims,const std::vecto
820899
{
821900
clear(); // make sure there is no data
822901

823-
m_.reset(new mxarray);
902+
m_ = new mxarray;
903+
m_->ref_ = 1;
824904
m_->class_ = mlOBJECT;
825905
m_->type_ = miMATRIX; // need to add some type checking here
826906
m_->flags_ = 0;
@@ -841,7 +921,8 @@ void matlabarray::createstringarray(const std::string& str)
841921
{
842922
clear(); // make sure there is no data
843923

844-
m_.reset(new mxarray);
924+
m_ = new mxarray;
925+
m_->ref_ = 1;
845926
m_->class_ = mlSTRING;
846927
m_->type_ = miUINT8;
847928
m_->flags_ = 0;

src/Core/Matlab/matlabarray.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,17 @@ class SCISHARE matlabarray : public matfilebase
102102

103103
class mxarray {
104104
public:
105+
int ref_; // reference counter: matlabarray is just a pointer to
106+
// this structure. By keeping the data and the pointer
107+
// separate a pointer (matlabarray class) can be
108+
// created to a subarray without having to copy this
109+
// subclass. Since there can be multiple pointers to
110+
// the subclasses the reference counter counts how
111+
// many instances of a matlabarray class point to this
112+
// one. Creating a new matlabarray class this counter
113+
// is increased and deleting the matlabarray class
114+
// will decrease the pointer. When ref_ hits zero the
115+
// structure is deleted.
105116
// matrix class information
106117

107118
mlclass class_; // type of the array
@@ -143,7 +154,7 @@ class SCISHARE matlabarray : public matfilebase
143154
// delete them all. This behavior is circumvented by only storing a
144155
// pointer to the real object.
145156

146-
boost::shared_ptr<mxarray> m_;
157+
mxarray* m_;
147158

148159
// raw access for friend classes to the data containers. These
149160
// functions make a copy of the container handle and will allow
@@ -169,7 +180,11 @@ class SCISHARE matlabarray : public matfilebase
169180
// Set the type of the data in the Matlab array
170181
void settype(mitype type);
171182

172-
// functions to maintain the matlabarray
183+
// function to create, copy, and destroy the object
184+
matlabarray(); // constructor of an empty matrix
185+
~matlabarray(); // destructor
186+
matlabarray(const matlabarray &m); // copy constructor
187+
matlabarray& operator= (const matlabarray &m); // assignment
173188

174189
// clear and empty
175190
void clear(); // empty matrix (no data stored at all)

0 commit comments

Comments
 (0)