有人可以向我解释指向指针的指针吗

标签 c pointers dynamic-arrays

我们最近在大学里讨论了指向指针的指针(例如:char **ppch),根据我的理解,它们可以用作二维数组,因为例如,char *pch 可以用作 char/string 的数组。

是这样还是我错过了什么?我不确定我们如何在程序中使用 P2P,或者我的理解是否接近正确。

有人可以举个例子吗?我们是否需要使用 malloc() 为这些 P2P 中的每个元素分配内存?

最佳答案

数组的一个固有属性是它们的元素在内存中是连续的。例如。

int foo[] = { 1, 2, 3, 4, 5, /* ... */ };
// ~> 1, 2, 3, 4, 5, ...

二维数组也不异常(exception):

int bar[][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
// ~> 1, 2, 3, 4, 5, 6, 7, 8, 9

而是指向某种类型的指针

int **qux;

就是这样。一个指向一个指针(或多个指针)的指针。当你分配内存时

int **qux = malloc(N * sizeof(*qux));

您将获得一个指向内存区域的指针,该区域足够大,可以容纳指向 N 个指向 int 的指针,而这些指针又可以指向其他内存区域:

int **qux = malloc(N * sizeof(*qux));
int value = 0;
for (size_t i = 0; i < N; ++i) {
    qux[i] = malloc(P * sizeof(**qux));
    for (size_t k = 0; k < P; ++k)
        qux[i][k] = ++value;
}

在内存中看起来像

+----------+                              +-----+
| qux[0] --|------------------------------|-> 1 |
| qux[1] --|-----------+                  |   2 |
| qux[2] --|---+       |       +-----+    |   3 |
| ...      |   |       +-------|-> 4 |    +-----+   
+----------+   |               |   5 |       
               |    +-----+    |   6 |
               +----|-> 7 |    +-----+
                    |   8 |
                    |   9 |
                    +-----+

所以不,指向指针的指针不是二维数组。类似的东西被称为“锯齿状数组”。

至于您的字符串示例,没有区别:

char **qux;  // a pointer to a (number of) pointers to char

qux = malloc(N * sizeof(*foo));

// just an array to fill the memory qux points to with:
char const *source[] = { "foo", "bar", "baz", "qux" /* I'm running out of names */ };
size_t index = 0;

for (size_t i = 0; i < N; ++i) {
    qux[i] = malloc((strlen(source[index]) + 1) * sizeof(**qux));
    strcpy(qux[i], source[index++]);
}

~>

+----------+                                                      +--------+
| foo[0] --|------------------------------------------------------|-> 'f'  |
| foo[1] --|-----------------------------------+                  |   'o'  |
| foo[2] --|----------------------+            |    +--------+    |   'o'  |
| foo[3] --|---+                  |            +----|-> 'b'  |    |   '\0' |   
| ...      |   |                  |                 |   'a'  |    +--------+   
+----------+   |    +--------+    |   +--------+    |   'r'  |
               +----|-> 'q'  |    +---|-> 'b'  |    |   '\0' |
                    |   'u'  |        |   'a'  |    +--------+
                    |   'x'  |        |   'z'  |
                    |   '\0' |        |   '\0' |
                    +--------+        +--------+

相比之下,真正的 char 二维数组:

char foo[][4] = { "foo", "bar", "baz", "qux" /*, ... */ };
// ~> 'f', 'o', 'o', '\0', 'b', 'a', 'r', '\0', 'b', 'a', 'z', '\0', 'q', 'u', 'x', '\0', ...

关于有人可以向我解释指向指针的指针吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53573254/

相关文章:

c++ - 在 C++ 中删除哈希表

C++ 指向 vector 行为的指针

java - 反向列表实现和指针理解

c++ - C++:段错误(核心已转储)

c++ - 派生类可以在类声明中定义基类数组的大小吗?

c++ - 在 C++ 类构造函数中初始化 Char 数组成员

c - 如何使用 openssl lib c 语言在算法 Diffie Hellman 中计算 2 个用户的共享 secret ?

c - linux cp命令实现复制多个文件到一个目录

c - 大无符号整数的 sscanf 和 %i/radix 检测

c++ - 具有动态分配大小和预定大小的简单数组内存分配