指向动态数组的指针
假设我在类中定义了一个平方网格:
Square (* grid)[];
奇怪的是,这似乎编译得很好。我认为它会出错,因为编译器不知道数组有多大? 无论如何, 这意味着它是一个指向数组的指针。然后为了初始化它,我这样做:
grid(new Square[width * height])
编译器不接受这一点,因为 new 语句返回一个指向正方形的指针,而不是指向正方形数组的指针。这样做是有道理的。现在,除了声明 Square ** grid 并循环遍历它并为 2D 数组的每一列进行单独分配之外,还有一种简单的方法可以完成我的要求吗?
Suppose I have a grid of squared defined like so in a class:
Square (* grid)[];
This, oddly, seems to compile fine. I would think it would error because the compiler doesn't know how big the array is?
Anyways,
it means it is a pointer to an array. Then to initialize it, I do:
grid(new Square[width * height])
This isn't accepted by the compiler, because the new
statement returns a pointer to squares rather than a pointer to an array of squares. It makes sense that it does that. Now, is there a simple way to accomplish what I'm asking, other than just declaring Square ** grid
and looping through it and doing separate allocations for each column of the 2D array?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是声明一个指向数组的指针,而不是一个数组;声明一个指向任何不完整类型的指针都可以,包括未知大小的数组。然而,这是一个非常不寻常的事情,而不是您想要的动态数组。
最容易使用的动态数组是:
初始化为
如果您确实想自己管理内存,则将数组指针更改为指向对象的指针:
初始化为
指针可以指向单个对象,也可以指向数组的开始;如果它确实指向一个数组,那么您可以像使用非动态数组一样对其使用
[]
。确保在使用完毕后将其释放(delete [] grid;
)。如果您想要一个二维数组,通常最简单的方法是使用一维数组,并将必要的算术包装在访问器函数中:
That's declaring a pointer to an array, not an array; it's fine to declare a pointer to any incomplete type, including an array of unknown size. However, it's quite an unusual thing to do, and not what you want for a dynamic array.
The easiest dynamic array to use is:
initialised as
If you really want to manage the memory yourself, then change your pointer-to-array to a pointer-to-object:
initialised as
A pointer can point to either a single object, or the start of an array; if it does point to an array, then you can use
[]
on it just like with a non-dynamic array. Make sure you deallocate it (delete [] grid;
) once you've finished with it.If you want a 2-dimensional array, it's often easiest to use a 1-dimensional array, and wrap the necessary arithmetic in an accessor function:
我相信 Square (* grid)[]; 起作用的原因是允许指向不完整类型的指针,并且没有大小的数组被视为不完整类型。
尽管看起来类型完美匹配却无法做到这一点,
这只是 C 设计中对数组类型进行特殊处理的错误的另一个表现。看起来
new
类型Square[]
的对象应该返回一个指向该类型对象的指针。然而,您并不是真正new
数组类型,而是new[]
元素类型Square
。new[]
的结果是指向元素类型的指针,符合数组的 C 约定。您可以使用强制转换来“修复”此问题以使用“正确”类型:
或者您可以以 C++ 方式进行操作并使用
std::vector
如果您有一个固定大小的数组,您可以使用
std::array
std::array
几乎修复了数组类型设计中所犯的所有错误。例如,std::array 无法“忘记”其大小,函数可以按值获取 std::array 参数(而对于原始数组,数组语法只是变成了指针的同义词),函数可以返回std::array
而它们却被莫名其妙地禁止返回数组(语法为int foo()[3];
),并且和std::array
不需要特殊的数组分配器new[]
,它必须与数组释放器delete[]
匹配(相反,您可以使用可以说foo = new std::array
然后“删除 foo;”)I believe the reason
Square (* grid)[];
works is because pointers to incomplete types are allowed, and an array without a size counts as an incomplete type.The reason that you can't do
even though it looks like the types match up perfectly is just another manifestation of the bug in the design of C where array types are treated specially. It seems like
new
ing an object of typeSquare[]
should return a pointer to an object of that type. However you're not reallynew
ing an array type, butnew[]
ing the element typeSquare
. The result ofnew[]
is a pointer to the element type, in line with the C convention for arrays.You can use a cast to 'fix' this to use the 'right' type:
Or you can just do it the C++ way and use a
std::vector
If you have a fixed size array you can use
std::array
std::array
pretty much fixes all the mistakes made in the design of array types. For examplestd::array
can't 'forget' its size, functions can takestd::array
parameters by value (whereas with raw arrays the array syntax just becomes a synonym for pointers), functions can returnstd::array
whereas they are inexplicably prohibited from returning arrays (The syntax would beint foo()[3];
), and withstd::array
there's no need for a special array allocatornew[]
which must be matched to an array deallocatordelete[]
(instead you can sayfoo = new std::array<int,3>
and then 'delete foo;')