C++ std::vector中push_back操作空间溢出


今天在做leetcode 705、706时候遇到一个错误。
题链接:https://leetcode.com/problems/design-hashmap/description/

  • [817] Design HashMap * *
    https://leetcode.com/problems/design-hashmap/description/ * *
    algorithms * Easy (48.96%) * Total Accepted: 9.2K * Total
    Submissions: 18.8K * Testcase Example:
    ‘[“MyHashMap”,“put”,“put”,“get”,“get”,“put”,“get”, “remove”,
    “get”]\n[[],[1,1],[2,2],[1],[3],[2,1],[2],[2],[2]]’ * * Design a
    HashMap without using any built-in hash table libraries. * * To be
    specific, your design should include these functions: * * *
    put(key, value) : Insert a (key, value) pair into the HashMap. If the
    value * already exists in the HashMap, update the value. * get(key):
    Returns the value to which the specified key is mapped, or -1 if *
    this map contains no mapping for the key. * remove(key) : Remove the
    mapping for the value key if this map contains the * mapping for the
    key. * * * * Example: * * * MyHashMap hashMap = new
    MyHashMap(); * hashMap.put(1, 1); * hashMap.put(2, 2);
  • hashMap.get(1); // returns 1 * hashMap.get(3); // returns -1 (not found) * hashMap.put(2, 1); // update the
    existing value * hashMap.get(2); // returns 1 *
    hashMap.remove(2); // remove the mapping for 2 *
    hashMap.get(2); // returns -1 (not found) * * * *
    Note: * * * All keys and values will be in the range of [0,
    1000000]. * The number of operations will be in the range of [1,
    10000]. * Please do not use the built-in HashMap library.

题目要求实现一个hash表
在实现过程中使用了vector进行模拟,但是令人想不到的是不是时间超时,而是空间溢出。QAQ???纳尼?
代码:

class MyHashMap {
    private:
    vector<int>m;
public:
    /** Initialize your data structure here. */
    MyHashMap() {
        for(int i=0;i<=1000000;i++)
        {
            m.push_back(-1);
        }
    }

    /** value will always be non-negative. */
    void put(int key, int value) {
        m[key]=value;
    }

    /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
    int get(int key) {
        return m[key];
    }

    /** Removes the mapping of the specified value key if this map contains a mapping for the key */
    void remove(int key) {
        m[key]=-1;
    }
};
/**
 * Your MyHashMap object will be instantiated and called as such:
 * MyHashMap obj = new MyHashMap();
 * obj.put(key,value);
 * int param_2 = obj.get(key);
 * obj.remove(key);
 */

C++ std::vector中push_back操作空间溢出_第1张图片
额好吧,到底怎么回事呢?QAQ


以下引自:https://blog.csdn.net/u011417820/article/details/79959825

我们在使用 vector 时​,最常使用的操作恐怕就是插入操作了(push_back),那么当执行该操作时,该函数都做了哪些工作呢?

该函数首先检查是否还有备用空间,如果有就直接在备用空间上构造元素,并调整迭代器 finish,使
vector变大。如果没有备用空间了,就扩充空间,重新配置、移动数据,释放原空间。​

其中​判断是否有备用空间,就是判断 finish是否与 end_of_storage 相等.如果

finish != end_of_storage,说明还有备用空间,否则已无备用空间。

当执行 push_back 操作,该 vector 需要分配更多空间时,它的容量(capacity)会增大到原来的 m
倍。​现在我们来均摊分析方法来计算 push_back 操作的时间复杂度。

假定有 n 个元素,倍增因子为 m。那么完成这 n 个元素往一个 vector 中的push_back​操作,需要重新分配内存的次数大约为
logm(n),第 i 次重新分配将会导致复制 m^i (也就是当前的vector.size() 大小)个旧空间中元素,因此 n 次
push_back操作所花费的总时间约为 n*m/(m - 1):

也就是说push_back会检查内存空间是不是够用(有没有备用空间),如果不够用,则从最后一个元素开始开辟空间。

C++ std::vector中push_back操作空间溢出_第2张图片


代码修改过后!

class MyHashMap
{
  private:
    vector<int> m;

  public:
    /** Initialize your data structure here. */
    MyHashMap()
    {
        m = std::vector<int>(1000001, -1);
    }

    /** value will always be non-negative. */
    void put(int key, int value)
    {
        m[key] = value;
    }

    /** Returns the value to which the specified key is mapped, or -1 if this map contains no mapping for the key */
    int get(int key)
    {
        return m[key];
    }

    /** Removes the mapping of the specified value key if this map contains a mapping for the key */
    void remove(int key)
    {
        m[key] = -1;
    }
};

/**
 * Your MyHashMap object will be instantiated and called as such:
 * MyHashMap obj = new MyHashMap();
 * obj.put(key,value);
 * int param_2 = obj.get(key);
 * obj.remove(key);
 */

C++ std::vector中push_back操作空间溢出_第3张图片
AC。

你可能感兴趣的:(leetcode)