2016-04-21 108 views
-1

我正在阅读一个关于BTree的程序,我碰到过这个:BTreeNode **C。我知道这是一个二维数组,但它初始化为C=new BTreeNode *[2*t];。我不明白这一点:这是一个2d数组与动态行和2t列? 谢谢。在C++中的双指针数组

+0

'2t'不是有效的语法。 – interjay

+0

对不起,它是2 * t,t是预定义值。 –

+2

这个问题如何与*数字签名算法*相关? – user2079303

回答

2

您可能很清楚double*是指向double元素的指针。以同样的方式,double**是指向double*元素的指针,它本身就是一个指针。再次,double***是指向double**元素的指针,依此类推。

当您将一个数组实例化为T类型时,通常会执行new T [size];。例如,对于double的数组,您编写new double[size];。如果你的类型T本身就是一个指针,它就是一样的:你写new double*[size];,你得到一个指针数组。

在你的情况,BTreeNode*是一个指向BTreeNode,并且BTreeNode**是指向BTreeNode*这是一个指向BTreeNode。当您通过执行new BTreeNode*[size];来实现它时,您会得到一个指向BTreeNode元素的指针数组。

但实际上,在这一步你没有二维数组,因为新分配的数组中的指针没有被分配。通常的做法是以下示例:

int num_rows = 10; 
int num_cols = 20; 
BTreeNode** C = new BTreeNode*[num_rows]; 
for(int i = 0; i < num_rows; i++) 
{ 
    // Then, the type of C[i] is BTreeNode* 
    // It's a pointer to an element of type BTreeNode 
    // This pointer not allocated yet, you have now to allocate it 
    C[i] = new BTreeNode [num_cols]; 
} 

不要忘记在使用后删除内存。通常的做法如下:

for(int i = 0; i < num_rows; i++) 
    delete [] C[i]; 
delete [] C; 
+0

不是说这里有什么_technically_错误,但我认为“常用的方法”是使用'vector'并让它处理所有的手动内存管理。我以为我们已经过去了最终用户,输入'new'和'delete',但这种模式似乎总是出现。这看起来更像是一个从C中勉强翻译过来的东西。而'vector'的'vector's似乎可以达到同样的效果,而不需要我们总是记住正确的'new'和'delete'。 –

+0

我不同意你的看法。首先,采购订单正在阅读一个现有的代码,他不写一些东西。其次,在某些情况下,这显然是必需的,就像使用blas和lapack库一样。 – Caduchon

+0

如果OP没有写点什么,那你为什么告诉他们如何写这个?当然,这可能是必需的,但这是例外而非规则;毕竟,“通常的方式”与“在某些情况下”不同。我所说的最好的建议是尽可能使用stdlib抽象,而不是手动内存管理,除非您是stdlib开发人员或者需要手动执行某些操作。我提到这一点,以防OP _thinks_他们需要'new'/'delete'但可能不需要。 –

0

语句C=new BTreeNode *[2*t];2*t类型的实例分配空间BTreeNode *,因此返回指向此类实例的第一个元素的类型BTreeNode **。这是数组的第一维,但是没有为第二维分配内存。

0

是的。如果数组被索引为列主要顺序(所以C [3] [4]是第4列的第5个元素),那么C可能会有可能具有不齐大小(不同大小)的列。

查找一些代码,对于每一列分配内存,即

C[i] = new BTreeNode[length]; 
在一个循环中对i,这将表明,该2D阵列具有每列具有相同的长度