unordered_map 迭代器迭代到空指针,无视可能性

Posted

技术标签:

【中文标题】unordered_map 迭代器迭代到空指针,无视可能性【英文标题】:unordered_map iterator iterates to null pointer, defying possibility 【发布时间】:2015-10-15 02:50:24 【问题描述】:

我将一堆虚拟对象存储在 unordered_map 中,然后遍历以删除它们。不知何故,它出现了一个键值对,其中值是一个空指针,尽管我很确定这是不可能的。

我制作的每个对象都包含我随机构建的一个非常大的字符串的一部分。我确保将至少 5 个字符的字符串交给这个对象的构造函数。

代码如下:

删除函数

bool delete_objects()
    Serial.println("deleting objects in 'store'");
    for(auto iter = store.begin(); iter != store.end(); iter++)
    
        Serial.println("\nDeleting the following element: \n");
        Serial.print("Key: ");
        Serial.println(iter->first);
        delay(1000);
        Serial.print("Value: ");
        Serial.println(iter->second->ShowMeWhatYouGot());
        delay(1000);

        delete iter->second;
        iter->second = nullptr;
        store.erase(iter);
     

    if(store.empty())
       return true;
    else
       return false;

分配对象的块(在此之前调用 delete_objects())

unsigned int index = 0;
unsigned int key = 0;
while(index < buff_string.length())
    int amount = (rand() % 51) + 5;
    DummyClass* dc = new DummyClass(buff_string.substr(index, amount));
    store[key] = dc;
    index += amount;
    key++;
    Serial.println("Created new DummyClass object");
    Serial.print("Free Memory: ");
    Serial.println(System.freeMemory());

类定义

using namespace std;

class DummyClass 
    private:
        char* _container;

    public:
        DummyClass()
        

        DummyClass(string input)
            _container = new char[input.length()];
            strcpy(_container, input.c_str());
        

        ~DummyClass()
            delete _container;
            _container = nullptr;
        

        char* ShowMeWhatYouGot()
            return _container;
        
;

串口输出,当key为0时SOS(崩溃,粒子芯片)

键:194 值:q->@Bs?tX/miN3K?[~2[mvTOSKPE34#5[@q8*d8BZwH`

删除以下元素:

键:193 值:9Hb^7-J(#z3H#0uqg

删除以下元素:

键:192 值:V$xZ>C$uMjxzxL?KQqvQp*MN3~Ce&yZbmop1$9xlkJM)jGja~PmY

删除以下元素:

键:191 值:yo*CVzE~2

删除以下元素:

键:190 值:[&PQakTV3^Aq?(ffV/*24xaXej]~T1^SfWiM3ATpk#CoQ

删除以下元素:

键:0 价值

【问题讨论】:

What happens if you call erase() on a map element while iterating from begin to end?的可能重复 【参考方案1】:

来自http://en.cppreference.com/w/cpp/container/unordered_map/erase

对已擦除元素的引用和迭代器无效。其他迭代器和引用不会失效。

之后

    store.erase(iter);

iter 无效。之后的表达式++iter 是导致未定义行为的原因。

解决问题的一种方法:

for(auto iter = store.begin(); iter != store.end(); /* iter++ */)
                                                    // Not needed

    // code
    // ...

    iter = store.erase(iter);
 

解决问题的另一种方法:

for(auto iter = store.begin(); iter != store.end(); iter++)

    // code
    // ...

    // Dont' call erase.
    // store.erase(iter);
 

// Clear the map.
store.clear();

【讨论】:

以上是关于unordered_map 迭代器迭代到空指针,无视可能性的主要内容,如果未能解决你的问题,请参考以下文章

将迭代器添加到指针

迭代 unordered_map 时如何获取指向键的指针?

为啥允许 std::unordered_map::rehash() 使迭代器无效?

为啥我不能增加 std::unordered_map 迭代器?

unordered_map 迭代器指向 end(),如何从 unordered_map 中检索键?

c ++ unordered_map迭代器在单个对象上