双指针是什么意思和指针日期类型的大小的malloc

时间:2019-01-07 14:50:59

标签: c pointers malloc

int **matrix, i, j;
matrix = malloc(5 * sizeof(int*));
*matrix = malloc(20 * sizeof(int));

我只是不了解双指针的概念以及它如何转换为二维数组(即为true)。 预先感谢。

3 个答案:

答案 0 :(得分:6)

从技术上讲,这里创建的不是二维数组,而是一个指针数组,每个指针都包含一个数组的起始地址。然后可以将其索引为好像是“真实的” 2D数组。

此行创建一个由5个指向int的指针组成的数组:

matrix = malloc(5 * sizeof(int*));

下一行创建单个数组20 int

*matrix = malloc(20 * sizeof(int));

但是就2D数组而言,这是不完整的,因为仅分配了一行。您需要遍历matrix指向的每个元素才能创建每一行:

int **matrix, i;

matrix = malloc(5 * sizeof(int*));
for (i=0; i<5; i++) {
    matrix[i] = malloc(20 * sizeof(int));
}

使用完此动态2D数组后,您需要以相反的顺序释放内存:

for (i=0; i<5; i++) {
    free(matrix[i]);
}
free(matrix);

这与真实的2D阵列在某些方面有所不同。首先,在真正的2D数组中,所有元素在内存中都是连续的,在这种情况下,指针数组和每个行数组都不是。

另一个区别是,当传递给函数时,不能像传递真实2D数组那样传递它。

对于简单的一维数组,无论是在编译时分配还是动态分配:

int a1[5];
int *a2 = malloc(5 * sizeof(int));

两者都可以传递给这样的函数:

void f(int *a);

但是对于2D数组:

int a[5][20];

它需要传递给这样的函数:

void f(int a[5][20]);

或等效地:

void f(int (*a)[20]);

动态2D数组需要传递给这样的函数:

void f(int **a);

答案 1 :(得分:6)

某些图片可能会有所帮助。

让我们从y开始,它是指向matrix的指针:

int

在第一次致电 int ** +--------+ | matrix |---??? +--------+ 之后,您将拥有以下内容:

malloc

您已为5个 int ** int * +--------+ +-----------+ | matrix |--->| matrix[0] | +--------+ +-----------+ | matrix[1] | +-----------+ | matrix[2] | +-----------+ | matrix[3] | +-----------+ | matrix[4] | +-----------+ 对象动态分配了空间,并且int *指向第一个对象。在第二次致电matrix之后,您将拥有以下内容(表达式malloc等效于*matrix-以下更多内容):

matrix[0]

您已为20个 int ** int * int +--------+ +-----------+ +---------------+ | matrix |--->| matrix[0] |--->| matrix[0][0] | +--------+ +-----------+ +---------------+ | matrix[1] | | matrix[0][1] | +-----------+ +---------------+ | matrix[2] | | matrix[0][2] | +-----------+ +---------------+ | matrix[3] | ... +-----------+ +---------------+ | matrix[4] | | matrix[0][19] | +-----------+ +---------------+ 对象动态分配了空间,并且int指向第一个对象。

因此,简而言之-每个matrix[0]是一个matrix[i][j]。每个int都指向matrix[i],因此每个matrix[i][0]必须是指向matrix[i]int的指针。 int *指向matrix,这意味着matrix[0]必须是指向matrixint *的指针。

请记住,数组下标表达式int **定义a[i]-给定地址*(a + i),偏移量a elements < / em>(不是字节!),然后引用结果。因此,i等效于*matrix,等效于*(matrix + 0)

现在,这里的不是真正的2D数组-您有一个指针序列,每个指针都可以指向matrix[0]对象序列的第一个(或一无所有)。阵列的“行”在内存中将很可能不相邻。在真正的2D数组中,所有数组元素都是连续的。给定

int

元素将如下所示:

int matrix[5][20];

编辑

指针到指针和2D数组之间的其他一些关键区别。首先,假设以下定义:

+---------------+
| matrix[0][0]  |
+---------------+
| matrix[0][1]  |
+---------------+
      ...
+---------------+
| matrix[0][19] |
+---------------+
| matrix[1][0]  |
+---------------+
| matrix[1][1]  |
+---------------+
       ...
+---------------+
| matrix[4][19] |
+---------------+
  1. 表达式int **ptr; int matrix[ROWS][COLS]; 的类型为ptr。表达式int **将从类型matrix“衰减”到类型int [ROWS][COLS](指向int (*)[COLS]的元素,指向COLS的元素数组);

  2. int给出指针本身的大小(4、8或其他一些字节数)。 sizeof ptr以字节为单位(sizeof matrix)给出整个数组的大小。

  3. 表达式ROW * COLS * sizeof (int)&matrixmatrix&matrix[0]都将产生相同的 value (数组的第一个元素),尽管表达式的类型将不同-分别为&matrix[0][0]int (*)[ROWS][COLS]int (*)[COLS]int (*)[COLS]。表达式int *&ptrptr&ptr[0]不会产生相同的值-&ptr[0][0]&ptr的值将不同于&ptr[0][0]ptr,表达式的类型将为&ptr[0]int ***int **int **

答案 2 :(得分:2)

我认为您需要以下条件:

int **matrix, i, j;
matrix = malloc(5 * sizeof(int*));
for (int i=0; i<5; i++)
    matrix[i] = malloc(20 * sizeof(int));

在这里,您首先为行分配一个指针数组。然后为每一行分配内存。