首页 > 解决方案 > C++ 动态数组没有请求大小

问题描述

在为 STL Multimap 创建自定义类时,我遇到了一种意外行为,即由 new 运算符创建的动态数组的大小不在 [] 之间。在下面的代码中,a.Set(3, 'c')存储在newKeynewSize大小为一的数组中,当它们的大小应该为二时。使用调试器表明,在那一行index中等于 1,所以大小应该是 2。程序不会产生任何异常,但也不会输出预期的结果c

作为澄清,使用调试器表明问题发生在将值设置在索引 1 中时newKey, newSize, newValue。它不会抛出任何异常,但也不会改变任何值。

template<typename T>
void Copy(T const* _source, T* _destiny, unsigned long _size)
{
    for (unsigned long i = 0; i < _size; i++)
    {
        _destiny[i] = _source[i];
    }
}
template<typename T>
void CopyNew(T const* _source, T* _destiny, unsigned long _size)
{
    T* target = new T[_size];
    for (unsigned long i = 0; i < _size; i++)
    {
        target[i] = _source[i];
    }
    _destiny = target;
}

template<typename T1, typename T2>
class Multimap
{
public:
    Multimap() {}
    unsigned long Get(T1 const& _key, T2** _return)
    {
        for (unsigned long i = 0; i < this->keySize_; i++)
        {
            if (_key == this->key_[i])
            {
                CopyNew<T2>(this->value_[i], *_return, this->valueSize_[i]);
                return i;
            }
        }
        *_return = 0;
        return this->keySize_;
    }
    unsigned long Get(T1 const& _key)
    {
        for (unsigned long i = 0; i < this->keySize_; i++)
        {
            if (_key == this->key_[i])
            {
                return i;
            }
        }
        return this->keySize_;    
    }
    int Set(T1 const& _key, T2 const& _value)
    {
        T2* target;
        unsigned long index = this->Get(_key, &target);
        if (target == 0)
        {
            T1* newKey = new T1[index + 1];
            unsigned long* newSize = new unsigned long[index + 1];
            T2** newValue = new T2*[this->keySize_ + 1];
            if (this->keySize_ != 0)
            {
                Copy(this->key_, newKey, index);
                delete[] this->key_;
                Copy(this->valueSize_, newSize, index);
                for (unsigned long i = 0; i < this->keySize_; i++)
                {
                    newValue[i] = new T2[this->valueSize_[i]];
                    Copy(this->value_[i], newValue[i], this->valueSize_[i]);
                    delete[] this->value_[i];
                }
                delete[] this->valueSize_;
            }
            newKey[index] = _key;
            newSize[index] = 0;
            this->key_ = newKey;
            this->valueSize_ = newSize;
            this->value_ = newValue;
            this->keySize_++;
        }
        unsigned long newSize = this->valueSize_[index]+1;
        T2* newValue = new T2[newSize];
        Copy(this->value_[index], newValue, newSize-1);
        newValue[newSize-1] = _value;
        this->valueSize_[index] = newSize;
        this->value_[index] = newValue;
        return newSize;
    }
    unsigned int GetSize()
    {
        return this->keySize_;
    }
protected:
    unsigned long keySize_ = 0;
    unsigned long* valueSize_ = 0;
    T1* key_ = 0;
    T2** value_ = 0;
};

int main()
{
    Multimap<int, char> a;
    a.Set(2, 'b');
    a.Set(3, 'c');
    char* b;
    a.Get(3, &b);
    std::cout << b[0];
}

标签: c++gccvisual-studio-code

解决方案


CopyNew论点_destiny应该是T*&(正如 WhozCraig 在评论中指出的那样)。否则,函数会更改参数,但不会更改传递给函数的变量。为了更改变量,您必须取消引用参数,因此它的类型必须是指针或对变量类型的引用。由于变量的类型是T*,参数类型应该是T**orT*&


推荐阅读