operator new []只分配一个元素而不管请求的数量(C ++)

时间:2013-05-16 00:21:43

标签: c++ arrays new-operator

对于介绍性的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;
}

此外,我已经能够按预期使用向量,但我担心我实际上只是访问数组之外​​的内存。它似乎被分配给程序,但它不会出现在数组中。

或者我只是感到困惑,根本没有问题?

感谢您的帮助!

3 个答案:

答案 0 :(得分:5)

  

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

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

new[]正确分配内存。不幸的是,您正在寻找的信息在标准C ++中不可用,而您的调试器提供了一种误导性的视图。

答案 1 :(得分:2)

没有问题。 sizeof(_arr)将始终返回4个字节,因为它实际上是指向数组的指针。 Visual Studio的调试器可以显示数组内容only if you tell it how many elements to display。由于您动态分配了数组,因此VS无法知道要显示的元素数量,否则。

答案 2 :(得分:2)

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

在您的设计和实现中还有其他一些奇怪的事情......如果它无法分配,请调用DoExit(退出应用程序?)但是为了实现这一点,您可以禁用{{1}之外的异常通过传递new,只是为了测试并抛出你自己的异常,你以后会抓到几行......

为什么不直接捕捉std::nothrow?如果你想禁用异常,那么为什么不在你检测到异常时采取行动,而不是仅仅为了在以后捕获几行呢?