二维数组动态申请分析

#include <stdio.h>

int main(void)
{
    int i, j;
    int *p = NULL;
    int **arr = NULL;
    int arry[4][3] = {{1, 2, 3},
                      {4, 5, 6},
                      {7, 8, 9},
                      {10, 11, 12}};

    printf("开始: ");
    printf("申请存储行指针的空间: ");
    arr = (int **)malloc(4* sizeof(int *));

    for (i = 0; i < 4; i++) {
        printf("申请二维数组第%d行数据的空间(即arr[%d]行的数据): ", i, i);
        arr[i] = (int *)malloc(3 * sizeof(int));
    }

    printf("按照二维数组方式访问动态申请的arr: ");
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 3; j++) {
            arr[i][j] = (i * 3) + j + 1;
        }
    }

    printf("直接定义二维数组arry的访问方法: ");
    for (i = 0; i < 4; i++) {
        printf("%p = %d, %p = %d, %p = %d,", 
               &(arry[i][0]), arry[i][0],
               &(arry[i][1]), arry[i][1],
               &(arry[i][2]), arry[i][2]);
    }
    
    printf("按照二维数组方式访问动态申请的arr: ");
    for (i = 0; i < 4; i++) {
        printf("%p = %d, %p = %d, %p = %d,", 
               &(arr[i][0]), arr[i][0],
               &(arr[i][1]), arr[i][1],
               &(arr[i][2]), arr[i][2]);
    }
    
    printf("arr[i][j]等效访问方式: ");
    for (i = 0; i < 4; i++) {
        for (j = 0; j < 3; j++) {
            // arr存储的是行指针,而*arr存储的是int型数据
            printf("%p = %d, ", *(arr + i) + j, *(*(arr + i) + j));
        }
    }

    
    printf("此处显示了arr,*arr和**arr的值: ");
    for (i = 0; i < 4; i++) {
        printf("%p = %p -> %d, ", (arr + i), *(arr + i), **(arr + i));
    }
    

    printf("直接定义arry[4][3]存储在连续12个int型栈内存空间中: ");
    p = arry;
    for (i = 0; i < 12; i++) {
        printf("%p = %d, ", p + i, *(p + i));
    }
    
    printf("动态申请的arr[4][3]存储在堆上,不能直接通过指针连续访问12个int型数据,");
    printf("因为malloc申请堆内存实际上是以链表方式来管理的,存在额外的表头空间: ");
    p = *arr;
    for (i = 0; i < 12; i++) {
        printf("%p = %d, ", p + i, *(p + i));
    }

    printf("释放二维数据的每一行数据的内存空间: ");
    for (i = 0; i < 4; i++) {
        free(arr[i]);
    }
    
    printf("释放行指针的内存空间: ");
    free(arr);
    printf("结束! ");
    
    return 0;
}

开始:

申请存储行指针的空间:
申请二维数组第0行数据的空间(即arr[0]行的数据):
申请二维数组第1行数据的空间(即arr[1]行的数据):
申请二维数组第2行数据的空间(即arr[2]行的数据):
申请二维数组第3行数据的空间(即arr[3]行的数据):

按照二维数组方式访问动态申请的arr:

直接定义二维数组arry的访问方法:
0x7ffd8ad5b820 = 1, 0x7ffd8ad5b824 = 2, 0x7ffd8ad5b828 = 3,
0x7ffd8ad5b82c = 4, 0x7ffd8ad5b830 = 5, 0x7ffd8ad5b834 = 6,
0x7ffd8ad5b838 = 7, 0x7ffd8ad5b83c = 8, 0x7ffd8ad5b840 = 9,
0x7ffd8ad5b844 = 10, 0x7ffd8ad5b848 = 11, 0x7ffd8ad5b84c = 12,

按照二维数组方式访问动态申请的arr:
0x2406050 = 1, 0x2406054 = 2, 0x2406058 = 3,
0x2406070 = 4, 0x2406074 = 5, 0x2406078 = 6,
0x2406090 = 7, 0x2406094 = 8, 0x2406098 = 9,
0x24060b0 = 10, 0x24060b4 = 11, 0x24060b8 = 12,

arr[i][j]等效访问方式:
0x2406050 = 1, 0x2406054 = 2, 0x2406058 = 3,
0x2406070 = 4, 0x2406074 = 5, 0x2406078 = 6,
0x2406090 = 7, 0x2406094 = 8, 0x2406098 = 9,
0x24060b0 = 10, 0x24060b4 = 11, 0x24060b8 = 12,

此处显示了arr,*arr和**arr的值:
0x2406020 = 0x2406050 -> 1,
0x2406028 = 0x2406070 -> 4,
0x2406030 = 0x2406090 -> 7,
0x2406038 = 0x24060b0 -> 10,

直接定义arry[4][3]存储在连续12个int型栈内存空间中:
0x7ffd8ad5b820 = 1, 0x7ffd8ad5b824 = 2, 0x7ffd8ad5b828 = 3,
0x7ffd8ad5b82c = 4, 0x7ffd8ad5b830 = 5, 0x7ffd8ad5b834 = 6,
0x7ffd8ad5b838 = 7, 0x7ffd8ad5b83c = 8, 0x7ffd8ad5b840 = 9,
0x7ffd8ad5b844 = 10, 0x7ffd8ad5b848 = 11, 0x7ffd8ad5b84c = 12,

动态申请的arr[4][3]存储在堆上,不能直接通过指针连续访问12个int型数据,
因为malloc申请堆内存实际上是以链表方式来管理的,存在额外的表头空间:
0x2406050 = 1, 0x2406054 = 2, 0x2406058 = 3,
0x240605c = 0, 0x2406060 = 0, 0x2406064 = 0,
0x2406068 = 33, 0x240606c = 0, 0x2406070 = 4,
0x2406074 = 5, 0x2406078 = 6, 0x240607c = 0,

释放二维数据的每一行数据的内存空间:
释放行指针的内存空间:

结束!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值