Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;数组大小初始化_C++_Arrays_Memory Management - Fatal编程技术网

C++ C++;数组大小初始化

C++ C++;数组大小初始化,c++,arrays,memory-management,C++,Arrays,Memory Management,我试图定义一个类。这就是我所拥有的: enum Tile { GRASS, DIRT, TREE }; class Board { public: int toShow; int toStore; Tile* shown; Board (int tsh, int tst); ~Board(); }; Board::Board (int tsh, int tst) { toShow = tsh; toStore = tst; s

我试图定义一个类。这就是我所拥有的:

enum Tile {
GRASS, DIRT, TREE 
};

class Board {
public:
    int toShow;
    int toStore;
    Tile* shown;
    Board (int tsh, int tst);
    ~Board();
};

Board::Board (int tsh, int tst) {
    toShow = tsh;
    toStore = tst;
    shown = new Tile[toStore][toStore]; //ERROR!
}

Board::~Board () {
    delete [] shown;
}
但是,我在指定的行中得到以下错误——只有分配数组的第一个维度可以具有动态大小

我希望能够做的是,而不是硬编码,将参数toShow传递给构造函数,并创建一个二维数组,其中只包含我希望显示的元素

然而,我的理解是,当调用并初始化构造函数时,它的大小将初始化为toStore的当前值。然后,即使toStore更改,内存也已分配给所示的阵列,因此大小不应更改。但是,编译器不喜欢这样


我对这一点的理解是否存在真正的误解?是否有人有一个修复程序,可以实现我想要的功能,而无需对数组大小进行硬编码

首先,如果要引用2D数组,必须声明指向指针的指针:

Tile **shown;

然后,查看错误消息。这是一种恰当的、可理解的英语。它说明了错误是什么
只有分配数组的第一个维度可以有动态大小。
意味着——猜猜看,只有分配数组的第一个维度可以有动态大小。就这样。如果你希望你的矩阵具有多个动态维度,使用C样式<代码> MalCube()/Cux>来维护指针,或者,对于C++来说,使用<代码>向量< /代码>,这是为了这个目的而做的。

< P>使用C++的容器,这就是它们的用途。
class Board {
public:
    int toShow;
    int toStore;
    std::vector<std::vector<Tile> > shown;
    Board (int tsh, int tst) : 
      toShow(tsh), toStore(tst), 
      shown(tst, std::vector<Tile>(tst))
    {
    };
};

...

    Board board(4, 5);
    board.shown[1][3] = DIRT;
课程板{
公众:
int toShow;
int托斯托尔;
std::所示的向量;
板(内部tsh,内部tst):
toShow(tsh)、toStore(tst),
显示(tst,标准::向量(tst))
{
};
};
...
董事会(4,5);
板。显示[1][3]=污垢;

> P> >理解C和C++中内存分配的工作原理是有好处的。
char x[10];
编译器将分配10个字节并记住起始地址,可能是在
0x12
(在现实生活中可能是一个更大的数字)

现在,编译器通过获取
x
的起始地址,即
0x12
,并添加
3*sizeof(char)
,从而查找
x[3]
。因此
x[3]
位于
0x15

这个简单的加法运算就是如何访问数组中的内存。对于二维数组来说,数学只是稍微复杂一些

char xy[20][30];
从某个位置开始分配600字节,可能是
0x2000
。正在访问

xy[4][3];
需要一些数学知识<代码>xy[0][0]、xy[0][1]、xy[0][2]…
将占用前30个字节。然后,
xy[1][0]、xy[1][1]、…
将占用字节31到60。它是乘法:
xy[a][b]
将位于地址
xy
,加上a*20,再加上b

这只有在编译器知道第一个维度有多长的情况下才有可能——您会注意到编译器需要知道数字“20”才能进行此计算

现在是函数调用。编译器几乎不关心您是否调用

foo(int* x);

因为在任何一种情况下,它都是一个字节数组,您可以传递起始地址,编译器可以执行额外的操作来查找
x[3]
或任何存在的位置。但对于二维数组,编译器需要知道上面示例中的幻数
20
。所以

foo(int[][] xy) {
    xy[3][4] = 5;     //compiler has NO idea where this lives 
                      //because it doesn't know the row dimension of xy!
}
但如果你指定

foo(int[][30] xy)

编译器知道该做什么。由于我不记得的原因,通常认为将其作为双指针传递是更好的做法,但这就是技术层面的情况。

您可以使用一维数组。您应该知道,二维数组被视为一维数组,当您需要可变大小时,可以使用此模式。例如:

int arr1[ 3 ][ 4 ] ;
int arr2[ 3 * 4 ] ;
它们是相同的,可以通过不同的符号访问它们的成员:

int x = arr1[ 1 ][ 2 ] ;
int x = arr2[ 1 * 4 + 2 ] ;
当然,arr1可以看作是一个3行x4列矩阵和3列x4列矩阵。
使用这种类型的多维数组,您可以通过单个指针访问它们,但必须了解其内部结构。它们是一维数组,被视为二维或三维数组。

让我告诉你我在需要三维数组时做了什么。这可能是一种矫揉造作,但它相当酷,可能会有所帮助,尽管这是一种完全不同的方式来做你想做的事情

我需要表示一个三维的细胞盒。只有一部分细胞被标记出来,并且是有意义的。有两种选择可以做到这一点。第一个,声明一个具有最大可能大小的静态3D数组,如果长方体的一个或多个维度小于静态数组中的相应维度,则使用其中的一部分

第二种方法是动态分配和取消分配数组。使用2D阵列相当费劲,更不用说3D了

数组解决方案定义了一个三维数组,其中感兴趣的单元格具有特殊值。大部分分配的内存是不必要的

我两个都甩了。相反,我转向STL地图。 我定义了一个名为Cell的结构,它有3个成员变量,x,y,z,它们表示坐标。构造函数
单元(x,y,z)
用于轻松创建这样的单元。
我首先定义了
操作符,您需要一个2D指针:
Tile**show。请仔细阅读一下。一旦你学会了如何做到这一点,就用
std::vector
来代替。@R.MartinhoFernandes,我不得不对你所描述的原因所付出的努力发笑。我曾经用C风格的varargs做过我自己的
xarray
。除了人们说的话-你在评论之前漏掉了一个分号。请看这个问题及其“最佳实践”的答案:
new*[SIZE]
会比
malloc
好吗?
foo(int[3][4]a)
foo(int[3][]a)
是b吗
int arr1[ 3 ][ 4 ] ;
int arr2[ 3 * 4 ] ;
int x = arr1[ 1 ][ 2 ] ;
int x = arr2[ 1 * 4 + 2 ] ;
map<Cell, Data>::iterator it = my_map.find(Cell(x0, y0, z0));
if (it != my_map.end()) { ...