2012-08-29 43 views
0

C++ newb here。我正在尝试使用指针来编写我自己的数组实现,并且我碰到了一堵墙,我不知道如何克服。用指针算术释放内存

我的构造函数抛出这个错误

array.cpp:40:35: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive] 

当我的数组初始化我希望它腾出数组整数中的所有空间。

Array::Array(int theSize){ 
size = theSize; 
int *arrayPointer = new int; 
int index = 0; 
while(theSize > index){ 
    *(arrayPointer + index) = new int; //This is the trouble line. 
    ++index; 
} 
} 

我在做什么错了stackoverflow?

+7

那么,对于初学者,你试图单独分配每个元素,当有一个内置的'new int [size]'语法来分配数组时;-) – Cameron

+0

使用'new int [size]'也同样糟糕(可能更糟糕)。对于一个容器,你通常希望使用'buffer = operator new(size);'来分配原始存储空间,接着放置new以在该空间中创建对象:'new(buffer + pos)int(value);' “int”很少,但其他类型更多。 –

+1

由于这个问题经常出现,并且几乎总是会产生一些我认为大部分都是错误的答案,所以我写了一篇[博客文章](http://coderscentral.blogspot.com/2012/08/c-dynamic-arrays)。 HTML)关于我认为更好的方式来处理这个问题。 –

回答

1

arrayPointer点到单个int,它不指向的int*阵列,其中该线路将需要:

*(arrayPointer + index) = new int; 

*(arrayPointer + index)类型是int,因此编译错误。

要分配的阵列的int

int* arrayPointer = new int[size]; 

如果这是为了初始化一个成员变量,则:

arrayPointer = new int[size]; 

否则arrayPointer将是本地的构造函数。由于该类现在拥有一个动态分配的成员,因此您需要实现复制构造函数和赋值运算符,或者防止复制(请参阅What is The Rule of Three?)。请记住在析构函数中使用delete[] arrayPointer


只要提及std::vector<int>,即使这是一个学习练习。

+0

我试过新的int [size],程序投了。是否有我需要使用的包含? – Breedly

+0

您是否在构造函数中重新声明'arrayPointer'(请参阅更新后的答案)? – hmjd

+0

仍然投掷,忘记发布错误。 'array.cpp :(。text + 0x1c):对运算符new [](unsigned int)的未定义引用'' 感谢您的链接,我会更多地阅读它。 – Breedly

0

你提到的试图设置一个INT *成INT变种的线=>解引用一个INT *提供一个INT:

*(arrayPointer + index) // is a int 

无论如何要在存储器移动(和解除引用存储器)你避难所” t保留。因此,您可以通过执行此指令来访问受保护的内存区域。

替换所有构造函数:

Array::Array(int theSize) 
{ 
    size = theSize; 
    arrayPointer = new int[theSize]; // Replace your local var with a member one. Else you will lose your array ;) 
} 
1

如下操作:

#include <cstddef> 

template <typename T> 
class Array 
{ 

public: 

    T* const arrayPointer; // arrayPointer can't be reallocated 
    const size_t size; // size can't change 

    Array(const int theSize) : arrayPointer(new T[theSize]), 
           size(theSize) {} 

    ~Array() { 
     delete[] arrayPointer; 
    } 

private: 

    Array(const Array& other) {} // forbid copy 

    Array& operator= (const Array& other) {} // forbid assignment 

} ; 
  • 为什么使用template <typename T>?所以你可以有任何类型的数组。
  • 为什么要使用new T[ theSize ]?所以你可以同时分配theSize元素。
  • 为什么要使用: arrayPointer(new T[ theSize ])?因此,如果分配失败(由于大的大小),对象失败,没有初始化。它被称为RAII。
  • 为什么要使用delete [] arrayPointer?因为你使用new[],你必须释放整个数组。
  • 为什么这些const的?避免任何人改变数组的大小并使字段不一致。
  • 这些私人方法是什么?他们禁止拷贝,所以没有人可以制作array1 = array2; delete array2;,什么会释放array1的arrayPointer。

使用(它会分配阵列10 INT的:)

Array<int> arr(10) ; 

访问:

arr.arrayPointer[ 0 ] = 5 ; 

注 - 您可以在范围0..9细胞访问arrayPointer。您可以将operator[]添加到您的班级,以避免使用arrayPointer并使用arr[ 0 ]

+0

这也是一个很好的答案,但它有点超出了范围。在接下来的几天里,你也应该对自己感觉良好! – Breedly

+0

@Breedly:我刚刚开始对自己感觉良好;)说真的,既然你是C++的新手,那么为什么不开始正确的方式呢?既然你想实现你自己的数组,我认为它是最好也是最安全的方法。用C++玩得开心。 – Grzegorz

+0

@Grzegorz不错的东西教,但也许为时尚早。现在你已经证明他需要一个析构函数,你可能需要谈论三条规则,否则它不会是“最好和最安全的方式”。 –