int ** p是什么意思?

时间:2016-09-13 03:30:11

标签: c++ arrays pointers

我知道当我们需要在动态内存中给出一个指针数组的指针时我们会使用它,但我不明白它是如何在堆栈中工作的。

这是否会使堆栈中的指针数组指向堆中的指针数组,或者它是否在堆栈中生成指向堆中指针数组的单个指针?如果是,那么

之间有什么区别
int **p = new int*[100]

int *p = new int[100]

提前致谢。我一直试图理解这个问题已经很久了,并且已经在线阅读了很多文档,但我仍然不明白这一点。

4 个答案:

答案 0 :(得分:6)

int **p在堆栈上声明一个指向堆上指针的指针。每个指针都指向堆上的整数或整数数组。

此:

int **p = new int*[100];

表示您在堆栈上声明了一个指针并对其进行了初始化,使其指向堆上的100个指针数组。现在,这100个指针中的每一个都无处可寻。 “无处”是指它们既不指向有效的记忆块,也不指示nullptr s。它们没有初始化,因此它们包含一些垃圾值,它们在分配指针之前存储在内存中。在使用之前,您应该在循环中为它们分配一些合理的东西。请注意,如果您为其分配p[0]的返回值,则不能保证p[99] - new指针指向相邻的内存区域。例如,如果您为每个p[i] = new int[200];分配内存,p[0][201]将不会引用p[1][2],但会导致未定义的行为。

而且:

int *p = new int[100];

是堆栈上的指针,指向堆上的100个整数数组。

答案 1 :(得分:0)

别担心,C中的指针和数组总是令人困惑。通常,当您声明一个数组,比如int类型时,您创建一个int类型的指针,指向将存储整数的连续内存块中的第一个元素。例如,如果我使用int *p_to_intarr = new int[3]有一个简单的整数数组,我会得到:

+++++++  <--------- p_to_intarr
| int |
+++++++
| int |
+++++++
| int |
+++++++

通常,如果我想要一个T类型的数组,我创建一个类似于T *ptr_to_Tarr = new T[3]的类型T的指针。

那么如果我想要一个int数组的数组怎么办?让我们用“int of int”的类型替换T in,这将给我们一个“int of int”数组。好吧,我们在第一个例子中说明了int *中的一个int数组的类型,因此一个int数组的数组将是:int* *ptr_to_arrayofintarr = new int*[3]。注意我们刚刚用int star替换了T.这通常写得更加整齐int **ptr_to_arrayofintarr = new int*[3]

所以int **p可以是指向二维数组的指针。它也可以是1d数组的引用;取决于具体情况:)

答案 2 :(得分:0)

new表达式求值为某种类型的指针,指向已在免费存储区(本质上是堆)中分配的内存,但不一定是 in 免费商店。 (它仍然可以在自由存储中取决于上下文;例如,考虑在免费存储中分配的对象的构造函数中的初始化列表。)

new初始化的对象当然是在免费商店中。

在您显示的赋值语句中,您可以看到等号左侧的new返回的指针类型,以及右侧的免费商店对象的类型new的。{因此,在第一种情况下,本地评估的唯一对象(即可能在堆栈上)是指向int的指针,在第二种情况下,是指向int的指针。自由空间中的对象是第一种情况下的指针数组和第二种情况下的简单数组。

请注意,仅仅因为第一个赋值中的数组包含指针并不意味着指针本身实际上指向任何东西; new不会神奇地递归地为它创建的数组中的任何指针所针对的对象分配空闲空间。 (无论如何这都没有多大意义。)

答案 3 :(得分:0)

**表示你有指向指针的指针。更实际的说,它意味着你有一个二维数组。

由于数组的每个元素也是指针,因此您还需要初始化这些指针:

for (int i = 0; i < 100; ++i)
    p[i] = new int[200];

初始化100x200阵列。您可以使用p[99][199]访问右下角。

当需要删除指针时,您必须反转该过程:

for (int i = 0; i < 100; ++i)
    delete [] p[i];
delete [] p;