c++ - C++ 动态数组没有请求大小
问题描述
在为 STL Multimap 创建自定义类时,我遇到了一种意外行为,即由 new 运算符创建的动态数组的大小不在 [] 之间。在下面的代码中,a.Set(3, 'c')
存储在newKey
和newSize
大小为一的数组中,当它们的大小应该为二时。使用调试器表明,在那一行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];
}
解决方案
CopyNew
论点_destiny
应该是T*&
(正如 WhozCraig 在评论中指出的那样)。否则,函数会更改参数,但不会更改传递给函数的变量。为了更改变量,您必须取消引用参数,因此它的类型必须是指针或对变量类型的引用。由于变量的类型是T*
,参数类型应该是T**
orT*&
推荐阅读
- java - 错误:无法在 Maven 项目中找到或加载主类
- c# - 防止表单集合中的重复
- screen - Androidthings 入门套件多点触控屏幕闪烁
- typescript - 生成偏函数的类型
- python - 使用opencv为移动对象保持相同的标签
- rust - #[allow(unused_must_use)] 一行
- unity3d - Unity 将 SerializedProperty 转换为 Generic
- c# - 如何从 VS 2017 的设置中获取当前的 Projects & Solutions 目录并使用 SDK 加载解决方案?
- java - Hibernate 无法删除子记录
- c# - 反序列化 json 的 C# 最佳对象或类结构