C ++自定义向量实现 - 指向不完整类型的指针的下标

时间:2022-11-30 09:44:01

As a part of a homework targeted on practicing deep/shallow copy concept I tried to implement very basic templated vector class (as well as simplistic string) to make further coding easier.

作为针对练习深/浅拷贝概念的家庭作业的一部分,我尝试实现非常基本的模板化矢量类(以及简单的字符串),以进一步简化编码。

I implemented data as array of pointers, however I encountered following warning with my destructor: Deleting pointer to incomplete type '<insert type for which class was instantiated>' may cause undefined behavior.

我将数据实现为指针数组,但是我在析构函数中遇到了以下警告:删除指向不完整类型“ <实例化类的插入类型> ”的指针可能会导致未定义的行为。

And also error Subscript of pointer to incomplete type 'myString[]' with copy constructor (which I believe is result of the same problematic approach as with destructor).

并且还有使用复制构造函数的指向不完整类型'myString []'的指针的错误下标(我认为这是与析构函数相同的问题方法的结果)。

I wrote destructor as simple delete [] m_data hoping that this is the right way to ensure that respective destructors of objects stored gets called.

我把析构函数写成简单的delete [] m_data,希望这是确保调用存储的对象的各个析构函数的正确方法。

Therefore I would like to ask

所以我想问一下

  1. whether there is any more proper way of doing this,
  2. 是否有更合适的方法,

  3. whether my approach to this class is somehow fundamentally flawed with respect to failing copy constructor.
  4. 对于失败的复制构造函数,我对这个类的方法是否存在某种根本上的缺陷。

template <typename T>
myVector<T>::myVector ( const myVector<T> & x ) : m_size(x.m_size), m_capacity(x.m_capacity), m_data( allocate(x.m_capacity) ) {
    for ( int i = 0; i < x . m_size; ++ i )
        m_data[i] = x . m_data[i];
}
template <typename T>
class myVector {
    static const size_t INIT_CAPACITY = 5;
    static const unsigned GROW_FACTOR = 2;

    size_t  m_size;
    size_t  m_capacity;
    T ( * m_data )[];

    template <typename U>
    friend std::ostream & operator << ( std::ostream & os, const myVector<U> & );

    static T (* allocate( size_t size )) [] {
        return (T (*)[])malloc(sizeof(T) * size );;
    }

    static T (* reallocate( T (* data)[], size_t size )) [] {
        return (T (*)[]) realloc( data, sizeof(T) * size );
    }

    void print( std::ostream & os ) const;

public:
                   myVector    ();
                   myVector    ( const myVector<T> & );
                  ~myVector    ();
    void           push_back   ( const T & );
    T &            operator[]  ( size_t idx );
    const T &      operator[]  ( size_t idx ) const;
    myVector<T> &  operator=   ( const myVector<T> & );
    T *            begin       ();
    T *            end         ();
    size_t         size        () const;
    void           clear       ();
};

1 个解决方案

#1


4  

"I impemented data as array of pointers" ...

“我将数据作为指针数组”......

"destructor as simple delete [] m_data" ...

“析构函数简单删除[] m_data”...

(T (*)[])malloc(sizeof(T) * size );

(T(*)[])malloc(sizeof(T)* size);

realloc...

Everything is wrong.

一切都错了。

One, you cannot use realloc when dealing with unknown C++ objects at all. You will get undefined behaviour and actual memory corruption.

一,在处理未知的C ++对象时,你不能使用realloc。您将获得未定义的行为和实际的内存损坏。

Two, you cannot mix malloc and delete (or delete[]). Use new[] with delete[], new with delete, and malloc with free (except you should not use malloc).

二,你不能混合malloc和删除(或删除[])。使用new [] with delete [],new with delete,malloc with free(除了你不应该使用malloc)。

Three, you are claiming to use an array of pointers, but you are declaring a pointer-to-array; then you are allocating an array of T, and casting it to the pointer-to-array type.

三,你声称要使用一个指针数组,但你要声明一个指向数组的指针;然后你分配一个T数组,并将其转换为指向数组的指针类型。

I think it's enough for now. Scrap the code in its entirety and start over. The correct, no-nonsense way is as follows:

我觉得现在已经足够了。完整地废弃代码并重新开始。正确的,没有废话的方式如下:

T* data; // that's your artray data
data = new T[size];  // allocation
delete [] data; // destruction

No casts of any kind ever. No pointers other than data. Resize by manually calling new[], copy old data in a loop with the assignment operator, then delete[] old data. There are more proper ways but they are considerably more complicated. Try mastering the basics first.

没有任何类型的演员阵容。没有数据以外的指针。通过手动调用new []调整大小,使用赋值运算符在循环中复制旧数据,然后删除[]旧数据。有更多正确的方法,但它们要复杂得多。首先尝试掌握基础知识。

#1


4  

"I impemented data as array of pointers" ...

“我将数据作为指针数组”......

"destructor as simple delete [] m_data" ...

“析构函数简单删除[] m_data”...

(T (*)[])malloc(sizeof(T) * size );

(T(*)[])malloc(sizeof(T)* size);

realloc...

Everything is wrong.

一切都错了。

One, you cannot use realloc when dealing with unknown C++ objects at all. You will get undefined behaviour and actual memory corruption.

一,在处理未知的C ++对象时,你不能使用realloc。您将获得未定义的行为和实际的内存损坏。

Two, you cannot mix malloc and delete (or delete[]). Use new[] with delete[], new with delete, and malloc with free (except you should not use malloc).

二,你不能混合malloc和删除(或删除[])。使用new [] with delete [],new with delete,malloc with free(除了你不应该使用malloc)。

Three, you are claiming to use an array of pointers, but you are declaring a pointer-to-array; then you are allocating an array of T, and casting it to the pointer-to-array type.

三,你声称要使用一个指针数组,但你要声明一个指向数组的指针;然后你分配一个T数组,并将其转换为指向数组的指针类型。

I think it's enough for now. Scrap the code in its entirety and start over. The correct, no-nonsense way is as follows:

我觉得现在已经足够了。完整地废弃代码并重新开始。正确的,没有废话的方式如下:

T* data; // that's your artray data
data = new T[size];  // allocation
delete [] data; // destruction

No casts of any kind ever. No pointers other than data. Resize by manually calling new[], copy old data in a loop with the assignment operator, then delete[] old data. There are more proper ways but they are considerably more complicated. Try mastering the basics first.

没有任何类型的演员阵容。没有数据以外的指针。通过手动调用new []调整大小,使用赋值运算符在循环中复制旧数据,然后删除[]旧数据。有更多正确的方法,但它们要复杂得多。首先尝试掌握基础知识。