BUG: HashPtrTable has problems with null pointers (issue #395)

- print and copy operations should not be allowed to dereference a
  nullptr.
This commit is contained in:
Mark Olesen
2017-01-26 18:00:33 +01:00
parent 1cb2966722
commit 2b9b2dd865
4 changed files with 95 additions and 30 deletions

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -31,15 +31,53 @@ Description
using namespace Foam;
template<class T>
void printTable(const HashPtrTable<T>& table)
{
Info<< table.size() << nl << "(" << nl;
for
(
typename HashPtrTable<T>::const_iterator iter = table.cbegin();
iter != table.cend();
++iter
)
{
const T* ptr = *iter;
Info<< iter.key() << " = ";
if (ptr)
{
Info<< *ptr;
}
else
{
Info<< "nullptr";
}
Info<< nl;
}
Info<< ")" << endl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main()
{
Foam::HashPtrTable<double> myTable;
myTable.insert("hello", new double(42.1));
HashPtrTable<double> myTable;
myTable.insert("abc", new double(42.1));
myTable.insert("def", nullptr);
myTable.insert("ghi", new double(3.14159));
Info<< myTable << endl;
// Info<< myTable << endl;
printTable(myTable);
HashPtrTable<double> copy(myTable);
// Info<< copy << endl;
printTable(copy);
Info<< copy << endl;
return 0;
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -45,7 +45,15 @@ Foam::HashPtrTable<T, Key, Hash>::HashPtrTable
{
for (const_iterator iter = ht.begin(); iter != ht.end(); ++iter)
{
this->insert(iter.key(), new T(**iter));
const T* ptr = *iter;
if (ptr)
{
this->insert(iter.key(), new T(*ptr));
}
else
{
this->insert(iter.key(), nullptr);
}
}
}
@ -62,24 +70,24 @@ Foam::HashPtrTable<T, Key, Hash>::~HashPtrTable()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, class Key, class Hash>
T* Foam::HashPtrTable<T, Key, Hash>::remove(iterator& it)
T* Foam::HashPtrTable<T, Key, Hash>::remove(iterator& iter)
{
T* elemPtr = *it;
HashTable<T*, Key, Hash>::erase(it);
return elemPtr;
T* ptr = *iter;
HashTable<T*, Key, Hash>::erase(iter);
return ptr;
}
template<class T, class Key, class Hash>
bool Foam::HashPtrTable<T, Key, Hash>::erase(iterator& it)
bool Foam::HashPtrTable<T, Key, Hash>::erase(iterator& iter)
{
T* elemPtr = *it;
T* ptr = *iter;
if (HashTable<T*, Key, Hash>::erase(it))
if (HashTable<T*, Key, Hash>::erase(iter))
{
if (elemPtr)
if (ptr)
{
delete elemPtr;
delete ptr;
}
return true;
@ -128,7 +136,15 @@ void Foam::HashPtrTable<T, Key, Hash>::operator=
for (const_iterator iter = rhs.begin(); iter != rhs.end(); ++iter)
{
this->insert(iter.key(), new T(**iter));
const T* ptr = *iter;
if (ptr)
{
this->insert(iter.key(), new T(*ptr));
}
else
{
this->insert(iter.key(), nullptr);
}
}
}

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -70,7 +70,7 @@ class HashPtrTable
//- Read from Istream using given Istream constructor class
template<class INew>
void read(Istream&, const INew& inewt);
void read(Istream& is, const INew& inewt);
//- Read from dictionary using given dictionary constructor class
template<class INew>
@ -91,17 +91,17 @@ public:
//- Construct from Istream using given Istream constructor class
template<class INew>
HashPtrTable(Istream&, const INew&);
HashPtrTable(Istream& is, const INew& inewt);
//- Construct from Istream using default Istream constructor class
HashPtrTable(Istream&);
HashPtrTable(Istream& is);
//- Construct from dictionary using default dictionary constructor
// class
HashPtrTable(const dictionary&);
HashPtrTable(const dictionary& dict);
//- Construct as copy
HashPtrTable(const HashPtrTable<T, Key, Hash>&);
HashPtrTable(const HashPtrTable<T, Key, Hash>& ht);
//- Destructor
@ -113,10 +113,10 @@ public:
// Edit
//- Remove and return the pointer specified by given iterator
T* remove(iterator&);
T* remove(iterator& iter);
//- Erase an hashedEntry specified by given iterator
bool erase(iterator&);
bool erase(iterator& iter);
//- Clear all entries from table
void clear();
@ -127,7 +127,8 @@ public:
// Member Operators
void operator=(const HashPtrTable<T, Key, Hash>&);
//- Copy assignment
void operator=(const HashPtrTable<T, Key, Hash>& rhs);
// IOstream Operators

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
\\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -61,7 +61,7 @@ void Foam::HashPtrTable<T, Key, Hash>::read(Istream& is, const INew& inewt)
if (delimiter == token::BEGIN_LIST)
{
for (label i=0; i<s; i++)
for (label i=0; i<s; ++i)
{
Key key;
is >> key;
@ -166,8 +166,11 @@ void Foam::HashPtrTable<T, Key, Hash>::write(Ostream& os) const
++iter
)
{
const T* ptr = iter();
ptr->write(os);
const T* ptr = *iter;
if (ptr)
{
ptr->write(os);
}
}
}
@ -226,7 +229,14 @@ Foam::Ostream& Foam::operator<<
++iter
)
{
os << iter.key() << token::SPACE << *iter() << nl;
const T* ptr = *iter;
os << iter.key();
if (ptr)
{
os << token::SPACE << *ptr;
}
os << nl;
}
// Write end delimiter