我的矢量有时有效,有时则无效

My vector works sometimes and othertimes it doesn't

本文关键字:无效 有效 我的      更新时间:2023-10-16

我正在尝试制作自己的向量,但是我遇到了以下问题:当我将_back 100次推动时,没有问题。当我推送1000时,程序不起作用

#include <iostream>
#include <stdlib.h>
#include <conio.h>
struct Exception {
    static const char* out_of_range;
};
const char* Exception::out_of_range = "[Error]: Out of range";
template < typename T >
struct vector {
    typedef T myType;
public:
    vector() { 
        m_vector = (myType*) malloc ( sizeof( myType ) );
        m_position = 0; 
    }
    template < typename ... Ts >
    vector(myType head, Ts ... tail) {
        m_position = 0;
        m_vector = (myType*) malloc( (sizeof ...( tail ) + 1) * sizeof( myType ) );
        this->push_back(head);
        (this->push_back(tail),...);
    }
    ~vector() { 
        free(m_vector); 
        m_vector = NULL;
    }
    void push_back( myType value ) {
        m_vector[ m_position ] = value;
        ++m_position;
        m_vector = (myType*) realloc(m_vector, m_position * sizeof(myType));
    }
    void pop_back() {
        --m_position;
        m_vector = (myType*)realloc( m_vector, m_position * sizeof (myType) );
    }
    myType at( size_t pos ) {
        try {
            if (pos < m_position) 
                return m_vector[ pos ];
            else throw Exception::out_of_range;
        } catch (const char* e) {
            printf("%s", e);
            return (myType){};
        }
    }
    inline myType& front() { return *m_vector; }
    inline myType& back() { return *(m_vector + size() -1); }
    inline myType* data() { return m_vector; }
    inline myType* begin() { return m_vector; }
    inline myType* end() { return (m_vector + size()); }
    inline myType operator[](size_t pos) { return m_vector[ pos ]; }
    inline size_t size() { return m_position; }
    inline bool empty () { return (begin() == end()? true:false); }
private:
    myType* m_vector;
    size_t m_position;
};

这是我的主要主要使用push_back 100次:

int main() {
    vector<int> v;
    for(int i = 0; i < 100; ++i) v.push_back(i);
    for(int i = 0; i < 100; ++i) std::cout << v[i];
}

在这里狩猎代码啊:

int main() {
    vector<int> v;
    for(int i = 0; i < 1000; ++i) v.push_back(i);
    for(int i = 0; i < 1000; ++i) std::cout << v[i];
}

用"不工作",我想说的是,当我被push_back插入100个值时,程序向我显示了从0到99的所有值...但是当我有1000个值时(我不知道't知道为什么)该程序仅显示一个黑屏,而没有更多

考虑

的第一个呼叫
void push_back(myType value) {
    m_vector[m_position] = value; // Store into 0
    ++m_position; // set `m_position` to 1
    m_vector = (myType*)realloc(m_vector, m_position * sizeof(myType)); // Allocate more space.
}

在最后一行中分配了多少空间?m_position * sizeof(myType)。这解析为1 * sizeof(myType)。足够1 myType的空间。换句话说,程序已经拥有的空间相同。这没有用。

让我们看下一个push_back

void push_back(myType value) {
    m_vector[m_position] = value; // Store into 1. There is no 1. Program now broken
    ++m_position; // set `m_position` to 2
    m_vector = (myType*)realloc(m_vector, m_position * sizeof(myType)); // Allocate more space.
}

下一个push_back将其写入无效的存储中。程序现在正式打破,没有进一步的调试。

我们如何解决此问题?

让我们忽略malloc和家人不处理复杂的数据结构的事实,而vector不会观察到三和五的规则。这些在其他问题中最好处理。我们如何使用realloc进行修复?

m_vector = (myType*) realloc(m_vector, (m_position +1) * sizeof(myType));

在直接的粗糙点上平滑。但这是地狱效率低下的。每次添加都会触发一个Realloc。这确实损害了性能。总o(1)在窗口替换为o(n)的窗口,每次复制,再加上潜在非常昂贵的内存分配。 1

更糟糕的是,删除物品时会发生什么?您失去了矢量中的数量,可能会发现自己realloc较小的缓冲区。yuck。

要正确执行此操作,首先添加m_capacity成员以跟踪可以存储多少数据,以便我们不必重新分配所需的金额小于所需的金额。

然后,我们在尝试存储之前测试空间数量,并可能重新分配。

void push_back( myType value ) {
    if (m_position >= m_capacity)
    { // need to reallocate
        m_capacity *= 2;
        myType * temp = (myType*) realloc(m_vector, m_capacity *sizeof(myType));
        // ask for more than is needed. Reduce number of reallocations needed
        // do not overwrite m_vector. realloc can fail to allocate and then where are you?
        if (temp != NULL) 
        { 
            m_vector = temp;
        }
        else
        {
             // handle error. Probably throw exception. Definitely exit function 
             // before trying to add new element
        }
    }
    m_vector[ m_position ] = value; // now guarantied to have space.
    ++m_position;
}

1 这不是完全正确的。您会发现的一件事是,提供的记忆通常并不像您要求的那样颗粒状。当程序要求X字节时,它可能会获得比X字节大的自由存储器的方便块。您曾经注意到,有时您可以在缓冲区的末端逃跑,并且该程序不会注意到并立即崩溃?这个额外的空间是原因之一。realloc经常可以利用这一点,并一遍又一遍地使用相同的分配,从而使程序合法地查看更多。但是,您不能指望这一点。

我假设您的代码背后的想法是M_Vector应该始终能够比目前拥有更多的值。然后,您的push_back funtion是错误的,对于m_position 1。

相关文章: