简体   繁体   English

int ** p是什么意思?

[英]What does int **p in mean?

I understand that we use this when we need to give a pointer to an array of pointers in the dynamic memory but what I don't understand is that how this works in the stack. 我知道我们在需要给动态内存中的指针数组提供指针时会用到它,但是我不明白的是它在堆栈中的工作方式。

Does this make an array of pointers in the stack too that is pointing to the array of pointers in the heap or does it make a single pointer in the stack that is pointing to the array of pointers in the heap? 这是否也使堆栈中的指针数组也指向堆中的指针数组,还是使堆栈中的单个指针指向堆中的指针数组? if yes, then what is the difference between 如果是,那么两者之间有什么区别

int **p = new int*[100]

and

int *p = new int[100]

Thanks in advance. 提前致谢。 I have been trying to understand this for a long time now and have read a lot of documentation online but I still don't understand this. 我已经很长时间了试图理解这一点,并且已经在线阅读了很多文档,但是我还是不明白。

int **p declares a pointer on the stack which points to pointer(s) on the heap. int **p在堆栈上声明一个指针,该指针指向堆上的指针。 Each of that pointer(s) point to an integer or array of integers on the heap. 每个指针都指向堆上的一个整数或整数数组。

This: 这个:

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

means that you declared a pointer on the stack and initialized it so that it points to an array of 100 pointers on heap. 表示您在堆栈上声明了一个指针并对其进行了初始化,以使其指向堆上包含100个指针的数组。 For now each of that 100 pointers point nowhere. 目前,这100个指针中的每一个都指向无处。 By "nowhere" I mean that they point neither to a valid chunk of memory, nor they are nullptr s. “无处”是指它们既不指向有效的内存块,也不是nullptr They are not initialized, thus they contain some garbage value which was in the memory before the pointers were allocated. 它们没有被初始化,因此它们包含一些在分配指针之前在内存中的垃圾值。 You should assign something sensible to them in a loop before usage. 您应该在使用前循环分配一些有意义的东西给他们。 Note that p[0] - p[99] pointers are not guaranteed to point to adjacent regions of memory if you assign return values of new to them. 需要注意的是p[0] - p[99]指针不能保证,如果你指定的返回值指向的内存相邻区域new给他们。 For example, if you allocate memory for each of them as p[i] = new int[200]; 例如,如果您为每个内存分配内存,则p[i] = new int[200]; , p[0][201] will not reference p[1][2] , but will lead to an undefined behavior. p[0][201]不会引用p[1][2] ,但是会导致未定义的行为。

And this: 和这个:

int *p = new int[100];

is a pointer on the stack which points to an array of 100 integers on the heap. 是堆栈上的一个指针,指向堆上100个整数的数组。

Don't worry, pointers and arrays in C are always a source of confusion. 不用担心,C语言中的指针和数组总是引起混乱。 In general, when you declare an array of, say type int, you create a pointer of type int that points to the first element in a contiguous block of memory that will store ints. 通常,声明一个类型为int的数组时,会创建一个int类型的指针,该指针指向将存储int的连续内存块中的第一个元素。 For example, if I have a simple array of ints using int *p_to_intarr = new int[3] , I get this: 例如,如果我有一个简单的使用int *p_to_intarr = new int[3]数组, int *p_to_intarr = new int[3]得到以下信息:

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

In general, if I want an array of type T, I create a pointer to type T like T *ptr_to_Tarr = new T[3] . 通常,如果我想要一个类型T的数组,则创建一个指向类型T的指针,例如T *ptr_to_Tarr = new T[3]

So what if I want an array of array of ints? 那么,如果我想要一个整数数组怎么办? Lets just replace the T in with the type of an "array of ints" and this will give us an array of "array of ints". 让我们用一个“整数数组”的类型替换T in,这将给我们一个“整数数组”的数组。 Well we just say in our first example that the type of an array of ints in int * , and so an array of array of ints would be: int* *ptr_to_arrayofintarr = new int*[3] . 好吧,我们只是在第一个示例中说过int *中的int *数组的类型,因此int *的数组的数组将是: int* *ptr_to_arrayofintarr = new int*[3] Note we just replaced the T with int star. 请注意,我们只是将T替换为int星型。 This is often written more neatly as int **ptr_to_arrayofintarr = new int*[3] . 这通常写得更整洁,如int **ptr_to_arrayofintarr = new int*[3]

So int **p could be a pointer to a 2d array. 因此int **p可以是指向2d数组的指针。 It could also be a reference to a 1d array; 它也可以是对一维数组的引用。 depends on the specific case :) 取决于具体情况:)

The new expression evaluates to a pointer of some type, pointing to memory that has been allocated in the free store (essentially the heap) but not necessarily in the free store. new表达式的计算结果为某种类型的指针, 指向已在免费存储区(实际上是堆)中分配但不一定免费存储区中分配的内存。 (It can still be in the free store depending on the context; for instance, consider an initialization-list in a constructor for an object being allocated in the free store.) (根据上下文,它仍然可以位于免费存储区中;例如,考虑在构造函数中的初始化列表,用于在免费存储区中分配的对象。)

The object(s) initialized by new is/are of course in the free store. new初始化的对象当然在免费商店中。

In the assignment statements you've shown, you can see the type of the pointer returned by new on the left side of the equals sign, and the type of the free store object(s) to the right of the new . 在还有你的赋值语句,您可以看到返回的指针类型new上等号的左边,而自由存储对象(S)到右边的类型new Thus the only object that is locally evaluated (ie might be on the stack) is, in the first case, a pointer-to-pointer-to-int, and in the second case, a pointer-to-int. 因此,在第一种情况下,本地评估的唯一对象(即可能在堆栈上)是指向int的指针,而在第二种情况下,则是指向int的指针。 The objects in free space are an array of pointers-to-ints in the first case and a simple array of ints in the second. 自由空间中的对象在第一种情况下是一个指向int的指针的数组,在第二种情况下是一个简单的int的数组。

Note that just because the array in the first assignment consists of pointers doesn't mean that the pointers themselves actually point to anything yet; 注意,仅仅因为第一个赋值中的数组由指针组成,并不意味着指针本身实际上已经指向任何东西; new does not magically recursively allocate free space for objects to be targeted by any pointers in an array it creates. new不会神奇地递归为它创建的数组中的任何指针所针对的对象分配可用空间。 (This wouldn't make much sense anyway.) (反正这没有多大意义。)

The ** means that you have a pointer to pointers. **表示您有一个指向指针的指针。 In more practical terms, it means you have a two-dimensional array. 实际上,这意味着您拥有一个二维数组。

Since each element of the array is also a pointer, you need to initialize those pointers as well: 由于数组的每个元素也是一个指针,因此您还需要初始化这些指针:

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

This initializes a 100x200 array. 这将初始化一个100x200的数组。 You can access the bottom-right corner with p[99][199] . 您可以使用p[99][199]访问右下角。

When it's time to delete the pointer you have to reverse the process: 是时候删除指针了,您必须逆转该过程:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM