IBM Support

IZ22824: UNORDERED_MAP NOT BEHAVING AS EXPECTED

Subscribe

You can track all active APARs for this component.

 

APAR status

  • Closed as program error.

Error description

  • The test case is showing unexpected behaviour from the
    unordered_map class. After using the operator= or copy
    constructor, erase of target object does not preform as expected
    - it affects both the source and target objects.
    
    Basically, when an element in umap2 is erased, _Dump shows it
    erased from both umap2 and umap1. Iteration then shows that the
    element still exists in umap2.
    
    Using iterators yields the same result.
    
    A variation of this test case with std::map yields expected
    results.
    
    
    TESTCASE:
    
    #include <iostream>
    #include <unordered_map>
    #include <string>
    
    using namespace std;
    using namespace std::tr1;
    
    int main()
    {
        unordered_map<string, size_t> umap1, umap2;
        umap1["Key"] = 1;
        umap2 = umap1;
    
        cout << "Dump before erase:" << endl;
        cout << "umap1: " << endl; umap1._Dump();
        cout << "umap2: " << endl; umap2._Dump();
    
        umap2.erase("Key");
    
        cout << "Dump after erase:" << endl;
        cout << "umap1: " << endl; umap1._Dump();
        cout << "umap2: " << endl; umap2._Dump();
    
        cout << "Iteration after erase:" << endl;
        cout << "umap1: " << endl;
    
        for(unordered_map<string, size_t>::iterator iter =
    umap1.begin();
            iter != umap1.end();
            ++iter) {
            const unordered_map<string, size_t>::value_type vt =
    *iter;
            cout << "key="     << vt.first.c_str()
                 << ", value=" << vt.second
                 << endl;
        }
    
        cout << "umap2: " << endl;
    
        for(unordered_map<string, size_t>::iterator iter =
    umap2.begin();
            iter != umap2.end();
            ++iter) {
            const unordered_map<string, size_t>::value_type vt =
    *iter;
            cout << "key="     << vt.first.c_str()
                 << ", value=" << vt.second
                 << endl;
        }
    }
    
    Compile with xlC -D__IBMCPP_TR1__ t.cpp
    
    
    ACTUAL OUTPUT:
    
    Dump before erase:
    umap1:
    Bucket count is 3
    Bucket 0:
    Bucket 1:  Key
    Bucket 2:
    
    umap2:
    Bucket count is 3
    Bucket 0:
    Bucket 1:  Key
    Bucket 2:
    
    Dump after erase:
    umap1:
    Bucket count is 3
    Bucket 0:
    Bucket 1:
    Bucket 2:
    
    umap2:
    Bucket count is 3
    Bucket 0:
    Bucket 1:
    Bucket 2:
    
    Iteration after erase:
    umap1:
    umap2:
    key=Key, value=1
    
    
    EXPECTED OUTPUT:
    
    The element should be completely removed from the target object
    without affecting the source object.
    

Local fix

  • n/a
    

Problem summary

  • The copy construction and copy-assignment of the unordered
    containers was incorrect.
    

Problem conclusion

  • An unordered container consists of a std::list that is used to
    store the contained elements, and an array of objects of type
    _Bucket.  Each _Bucket is essentially a pair of pointers that
    reference elements in the list.  After a copy was performed, all
    the elements of the source container were copied into the target
    container, but each _Bucket in the target container referenced
    the elements of the source container's list, rather than
    elements of the target container's list.
    

Temporary fix

Comments

APAR Information

  • APAR number

    IZ22824

  • Reported component name

    XLC C++ AIX

  • Reported component ID

    5724M1200

  • Reported release

    800

  • Status

    CLOSED PER

  • PE

    NoPE

  • HIPER

    NoHIPER

  • Special Attention

    NoSpecatt

  • Submitted date

    2008-05-20

  • Closed date

    2008-05-20

  • Last modified date

    2008-05-20

  • APAR is sysrouted FROM one or more of the following:

    IZ18515

  • APAR is sysrouted TO one or more of the following:

Fix information

  • Fixed component name

    XLC C++ AIX

  • Fixed component ID

    5724M1200

Applicable component levels

[{"Line of Business":{"code":"LOB08","label":"Cognitive Systems"},"Business Unit":{"code":"BU054","label":"Systems w\/TPS"},"Product":{"code":"SSJT9L","label":"XL C\/C++"},"Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"8.0"}]

Document Information

Modified date:
04 October 2021