指向动态数组的指针

时间:2012-02-06 21:24:52

标签: c++ multidimensional-array new-operator

假设我在类中定义了一个平方网格:

Square (* grid)[];
奇怪的是,这似乎编译得很好。我认为它会出错,因为编译器不知道数组有多大? 无论如何, 这意味着它是一个指向数组的指针。然后初始化它,我做:

grid(new Square[width * height])

编译器不接受这一点,因为new语句返回指向正方形的指针而不是指向正方形数组的指针。这样做是有意义的。现在,有没有一种简单的方法来完成我的要求,除了声明Square ** grid并循环遍历它并为2D数组的每一列进行单独的分配?

2 个答案:

答案 0 :(得分:3)

Square (* grid)[];
  奇怪的是,这似乎编译得很好。我认为它会出错,因为编译器不知道数组有多大?

那是声明指向数组的指针,而不是数组;可以声明指向任何不完整类型的指针,包括未知大小的数组。但是,这是一件非常不寻常的事情,而不是你想要的动态数组。

  

现在,有一种简单的方法可以完成我的要求吗?

最简单的动态数组是:

std::vector<Square> grid;

初始化为

grid(width * height)

如果您真的想自己管理内存,那么将指向数组的指针更改为指向对象的指针:

Square * grid;

初始化为

grid(new Square[width * height])

指针可以指向单个对象,也可以指向数组的开头;如果它确实指向一个数组,那么就可以像使用非动态数组一样使用[]。确保在完成后将其解除分配(delete [] grid;)。

如果你想要一个二维数组,通常最容易使用一维数组,并在访问器函数中包含必要的算术:

Square & get_square(size_t row, size_t col) {
    return grid[row * width + col];
}

答案 1 :(得分:0)

我认为Square (* grid)[];的原因是因为允许指向不完整类型的指针,而没有大小的数组会被视为不完整的类型。

你不能做的原因

Square (* grid)[] = new Square[width * height];

即使它看起来完全匹配的类型只是C设计中的错误的另一种表现形式,其中数组类型被特别处理。似乎new类型为Square[]的对象应返回指向该类型对象的指针。但是,您并不是new数组类型,而是new[]元素类型Squarenew[]的结果是指向元素类型的指针,符合数组的C约定。

您可以使用强制转换来“修复”此选项以使用“正确”类型:

// pretend array types behave rationally
Square (* grid)[] = (Square (*)[]) new Square[width * height];
(*grid)[3] = 10;

// the above is equivalent to the following
Square *grid = new Square[width * height];
grid[3] = 10;  

或者您可以使用C ++方式并使用std::vector

std::vector<Square> grid(width * height);

如果您有固定大小的数组,则可以使用std::array

std::array<Square,10> *grid = new std::array<Square,10>;

std::array几乎修复了数组类型设计中的所有错误。例如std::array不能“忘记”它的大小,函数可以按值获取std::array个参数(而对于原始数组,数组语法只是成为指针的同义词),函数可以返回{{1}然而,它们被莫名其妙地禁止返回数组(语法为std::array),而int foo()[3];则不需要特殊的数组分配器std::array,它必须与数组deallocator {匹配} { {1}}(相反,您可以说new[]然后'删除foo;')