incubator-stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Travis Vitek (JIRA)" <j...@apache.org>
Subject [jira] Updated: (STDCXX-618) purify reports free memory read in 21.string.append test
Date Wed, 24 Oct 2007 23:11:53 GMT

     [ https://issues.apache.org/jira/browse/STDCXX-618?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]

Travis Vitek 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.

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





  was:
While investigating purify errors in 21.string.append.cpp, I ran into bunch FMR failures.
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;
}





        Summary: purify reports free memory read in 21.string.append test  (was: purify free
memory read in 21.string.append.cpp)

> 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
>            Reporter: Travis Vitek
>            Priority: Minor
>             Fix For: 4.2.1
>
>         Attachments: 21.string.append.log
>
>
> 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;
> }

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message