You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@stdcxx.apache.org by "Martin Sebor (JIRA)" <ji...@apache.org> on 2008/02/01 05:39:07 UTC
[jira] Updated: (STDCXX-618) purify reports free memory read in
21.string.append test
[ https://issues.apache.org/jira/browse/STDCXX-618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Martin Sebor updated STDCXX-618:
--------------------------------
Description:
While investigating purify errors in 21.string.append.cpp, I ran into bunch FMR failures [this same failure occurs in other tests also]. They point to a legitimate bug in basic_string::replace() and possibly others like vector::insert(). I'm not really sure what the best approach for fixing this is because the issue itself is a little weird. There is also the issue of exception safety which makes it a little more interesting.
{noformat}
#include <cassert>
#include <string>
#include <vector>
template <class _IteratorT>
struct dumb_input_iterator
{
typedef typename _IteratorT::value_type value_type;
typedef typename _IteratorT::difference_type difference_type;
typedef typename _IteratorT::pointer pointer;
typedef typename _IteratorT::reference reference;
typedef std::input_iterator_tag iterator_category;
dumb_input_iterator (const _IteratorT &__rhs)
: _C_iter (__rhs) {}
reference operator* () const {
return _C_iter.operator*();
}
pointer operator-> () const {
return _C_iter.operator->();
}
dumb_input_iterator& operator++ () {
return _C_iter.operator++(), *this;
}
dumb_input_iterator operator++ (int) {
dumb_input_iterator __tmp(*this);
_C_iter.operator++();
return __tmp;
}
bool
operator== (const dumb_input_iterator &__rhs) const {
return _C_iter == __rhs._C_iter;
}
bool
operator!= (const dumb_input_iterator &__rhs) const {
return !(_C_iter == __rhs._C_iter);
}
private:
_IteratorT _C_iter;
};
int main()
{
// i'm not exactly sure why you'd do this, but the following code
// creates input iterators on top of bidirectional iterators. when
// passing an input iterator to these [and possibly other] methods
// it is assumed that the iterator does not refer to elements inside
// the container, which is wrong.
size_t n;
typedef std::string string;
string s(16, 'a');
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = s.size ();
const dumb_input_iterator<string::iterator> db (s.begin ());
const dumb_input_iterator<string::iterator> de (s.end ());
s.append (db, de);
// s.append (s.begin (), s.end ()); // works as expected
for (; i < s.size (); ++i)
assert (s[i] == 'a');
}
typedef std::vector<int> vector;
vector v(16, 1);
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = v.size ();
const dumb_input_iterator<vector::iterator> db (v.begin ());
const dumb_input_iterator<vector::iterator> de (v.end ());
v.insert (v.end (), db, de);
// v.insert (v.end (), v.begin (), v.end ()); // works as expected
for (; i < v.size (); ++i)
assert (v[i] == 1);
}
return 0;
}
{noformat}
was:
While investigating purify errors in 21.string.append.cpp, I ran into bunch FMR failures [this same failure occurs in other tests also]. They point to a legitimate bug in basic_string::replace() and possibly others like vector::insert(). I'm not really sure what the best approach for fixing this is because the issue itself is a little weird. There is also the issue of exception safety which makes it a little more interesting.
#include <cassert>
#include <string>
#include <vector>
template <class _IteratorT>
struct dumb_input_iterator
{
typedef typename _IteratorT::value_type value_type;
typedef typename _IteratorT::difference_type difference_type;
typedef typename _IteratorT::pointer pointer;
typedef typename _IteratorT::reference reference;
typedef std::input_iterator_tag iterator_category;
dumb_input_iterator (const _IteratorT &__rhs)
: _C_iter (__rhs) {}
reference operator* () const {
return _C_iter.operator*();
}
pointer operator-> () const {
return _C_iter.operator->();
}
dumb_input_iterator& operator++ () {
return _C_iter.operator++(), *this;
}
dumb_input_iterator operator++ (int) {
dumb_input_iterator __tmp(*this);
_C_iter.operator++();
return __tmp;
}
bool
operator== (const dumb_input_iterator &__rhs) const {
return _C_iter == __rhs._C_iter;
}
bool
operator!= (const dumb_input_iterator &__rhs) const {
return !(_C_iter == __rhs._C_iter);
}
private:
_IteratorT _C_iter;
};
int main()
{
// i'm not exactly sure why you'd do this, but the following code
// creates input iterators on top of bidirectional iterators. when
// passing an input iterator to these [and possibly other] methods
// it is assumed that the iterator does not refer to elements inside
// the container, which is wrong.
size_t n;
typedef std::string string;
string s(16, 'a');
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = s.size ();
const dumb_input_iterator<string::iterator> db (s.begin ());
const dumb_input_iterator<string::iterator> de (s.end ());
s.append (db, de);
// s.append (s.begin (), s.end ()); // works as expected
for (; i < s.size (); ++i)
assert (s[i] == 'a');
}
typedef std::vector<int> vector;
vector v(16, 1);
// loop in an attempt to ensure internal buffer reallocation
for (n = 0; n < 8; ++n)
{
size_t i = v.size ();
const dumb_input_iterator<vector::iterator> db (v.begin ());
const dumb_input_iterator<vector::iterator> de (v.end ());
v.insert (v.end (), db, de);
// v.insert (v.end (), v.begin (), v.end ()); // works as expected
for (; i < v.size (); ++i)
assert (v[i] == 1);
}
return 0;
}
Removed formatting.
> purify reports free memory read in 21.string.append test
> --------------------------------------------------------
>
> Key: STDCXX-618
> URL: https://issues.apache.org/jira/browse/STDCXX-618
> Project: C++ Standard Library
> Issue Type: Bug
> Components: 21. Strings
> Affects Versions: 4.2.0
> Reporter: Travis Vitek
> Assignee: Travis Vitek
> Priority: Minor
> Fix For: 4.2.1
>
> Attachments: 21.string.append.log
>
> Original Estimate: 4h
> Remaining Estimate: 4h
>
> While investigating purify errors in 21.string.append.cpp, I ran into bunch FMR failures [this same failure occurs in other tests also]. They point to a legitimate bug in basic_string::replace() and possibly others like vector::insert(). I'm not really sure what the best approach for fixing this is because the issue itself is a little weird. There is also the issue of exception safety which makes it a little more interesting.
> {noformat}
> #include <cassert>
> #include <string>
> #include <vector>
> template <class _IteratorT>
> struct dumb_input_iterator
> {
> typedef typename _IteratorT::value_type value_type;
> typedef typename _IteratorT::difference_type difference_type;
> typedef typename _IteratorT::pointer pointer;
> typedef typename _IteratorT::reference reference;
> typedef std::input_iterator_tag iterator_category;
> dumb_input_iterator (const _IteratorT &__rhs)
> : _C_iter (__rhs) {}
> reference operator* () const {
> return _C_iter.operator*();
> }
> pointer operator-> () const {
> return _C_iter.operator->();
> }
> dumb_input_iterator& operator++ () {
> return _C_iter.operator++(), *this;
> }
> dumb_input_iterator operator++ (int) {
> dumb_input_iterator __tmp(*this);
> _C_iter.operator++();
> return __tmp;
> }
> bool
> operator== (const dumb_input_iterator &__rhs) const {
> return _C_iter == __rhs._C_iter;
> }
> bool
> operator!= (const dumb_input_iterator &__rhs) const {
> return !(_C_iter == __rhs._C_iter);
> }
> private:
> _IteratorT _C_iter;
> };
> int main()
> {
> // i'm not exactly sure why you'd do this, but the following code
> // creates input iterators on top of bidirectional iterators. when
> // passing an input iterator to these [and possibly other] methods
> // it is assumed that the iterator does not refer to elements inside
> // the container, which is wrong.
> size_t n;
> typedef std::string string;
> string s(16, 'a');
> // loop in an attempt to ensure internal buffer reallocation
> for (n = 0; n < 8; ++n)
> {
> size_t i = s.size ();
> const dumb_input_iterator<string::iterator> db (s.begin ());
> const dumb_input_iterator<string::iterator> de (s.end ());
> s.append (db, de);
> // s.append (s.begin (), s.end ()); // works as expected
> for (; i < s.size (); ++i)
> assert (s[i] == 'a');
> }
> typedef std::vector<int> vector;
> vector v(16, 1);
> // loop in an attempt to ensure internal buffer reallocation
> for (n = 0; n < 8; ++n)
> {
> size_t i = v.size ();
> const dumb_input_iterator<vector::iterator> db (v.begin ());
> const dumb_input_iterator<vector::iterator> de (v.end ());
> v.insert (v.end (), db, de);
> // v.insert (v.end (), v.begin (), v.end ()); // works as expected
> for (; i < v.size (); ++i)
> assert (v[i] == 1);
> }
> return 0;
> }
> {noformat}
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.