1

对于介绍性 C++ 课程作业(当然是今晚到期!),我必须实现自己的 Vector 类。几乎一切似乎都在工作,除了我在 VS2012 的调试器中注意到,似乎实际上只分配了 _arr[] 中的一个元素。不管请求的元素数量(n)是多少,它只分配数组中的一个元素。我跟踪了调试跟踪,new[] 收到了 20 个请求(请求的 5 个元素 * 4 个字节的 int),但是当我稍后检查 sizeof(_arr) 时,它只显示 4 个字节。其他 16 个字节到哪里去了?为什么缺少其他 4 个元素?没有错误指示,也没有抛出异常。

template <typename T>
void Vector<T>::Add ( const T& val )
{
    // Check if a new element would grow beyond the current allocation.
    if ( _length + 1 > _allocSize )
    {
        size_t n = 5; // <-- Set statically for this example
        // Create a new array of the requested size
        try
        {
            T* newArr = new (std::nothrow) T[n]();
            if( newArr == NULL )
                throw VectorException( VECTOR_CANNOT_GROW,
                     "Vector::Add", _length, n );
            // Copy the old array into the new array
            if( _length > 0 )
                for( size_t idx = 0; idx < _length; idx++ )
                    newArr[idx] = _arr[idx];
            // Delete any dynamic memory allocated to the old array.
            delete[] _arr;

            // Note: _sizeof(newArr) here indicates only 4 bytes!!!

            // Point _arr to the new array
            _arr = newArr;

            // Update the allocated size to the new array size
            _allocSize = n;
        }
        catch ( VectorException &cException )
        {
            cerr << cException.GetError() << endl;
            DoExit( cException.GetErrorNum() );
        }
    }
    // Add the new item to the end of the array and update the length.
    _arr[ _length++ ] = val;
}

此外,我已经能够按预期使用向量,但恐怕我实际上只是在访问正确的数组之外的内存。它似乎被分配给程序,但它没有出现在数组中。

还是我只是糊涂了,真的一点问题都没有?

谢谢你的帮助!

4

3 回答 3

5

当我稍后检查 sizeof(_arr) 时,它只显示 4 个字节

sizeof是一个编译时特性。 new[]根据运行时参数分配内存。最终结果是sizeof没有您要求的信息。相反,它告诉您指向数组的指针是 4 个字节,这对于 32 位代码是正常的。

new[]正确分配内存。不幸的是,您要查找的信息在标准 C++ 中不可用,并且您的调试器提供了对事物的误导性视图。

于 2013-05-16T00:27:40.653 回答
2

没有问题。sizeof(_arr) 将始终返回 4 个字节,因为它实际上是一个指向数组的指针。Visual Studio 的调试器只有在您告诉它要显示多少个元素时才能可视化数组内容。由于您动态分配了数组,否则 VS 无法知道要显示多少元素。

于 2013-05-16T00:29:02.867 回答
2

运算符将sizeof告诉您传递给它的类型或对象的大小。在这种情况下,它是 a T*,并且指针通常是 32/64 位(在您的情况下,您似乎正在构建一个 32 位二进制文​​件)。结果与指向缓冲区中可能存储的数据量无关。

在您的设计和实现中还有其他一些奇怪的事情......如果它无法分配您DoExit的调用(退出应用程序?)但是要到达那里,您可以new通过 pass禁用异常std::nothrow,只是为了测试并抛出您自己的异常你稍后会赶上几行...

为什么不std::bad_alloc直接抓?如果您想禁用异常,为什么不在检测到问题时采取行动,而不是为了稍后捕获几行而抛出?

于 2013-05-16T00:29:21.977 回答