动态数组(一维二维)探秘

隐身守侯 提交于 2019-12-24 18:38:12

因为做leetcode的一道算法题https://leetcode-cn.com/problems/regular-expression-matching/,需要用到二维数组,结果自己在理解和使用上有很大误解,所以单独拿出来,从内存等各方面透彻的梳理一遍。

一维数组

char * a = (char*)malloc(8 * sizeof(char));
    memset(a, 0, 8);
    for (int i = 0; i < 8; i++)
    {
        *(a + i) = 'a' + i;
    }
    for (int i = 0; i < 8; i++)
    {
        cout << *(a+i);
    }
    for (int i = 0; i < 8; i++)
    {
        cout << a[i];
    }
    free(a);

输出内容abcdefghabcdefgh

这样申请与char a[8]是一样的,不管是底层实现还是使用,都是一样的,这就是一个8个字节长度的数组。我们看内存,也是一段连续的数据。

释放内存的时候,系统可以根据内存管理把这连续的8个字节的空间回收。

二维数组

我们先看一下正常的用法

char a[8][4] = { 0 };
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            a[i][j] = 'a' + i;
        }
    }
    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            cout << a[i][j];
        }
    }

输出结果 aaaabbbbccccddddeeeeffffgggghhhh

我们看一下内存

是一段连续的内存,数组a[n][m],按照m跳度,前m个是第一个n的序列,然后是第二个n的m个序列,实际上这是一个一维数组。

看看我们第一种实现

char** a = (char**)malloc(8 * sizeof(char*));
        for (int i = 0; i < 8; i++)
        {
            *(a + i) = (char*)malloc(4 * sizeof(char));
        }
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                a[i][j] = 'a' + i;
            }
        }
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                cout << a[i][j];
            }
        }

a是一个数组,也就是a指向了申请的一块空间,空间是8个char*大小。然后为a的每一个数组元素,又指向了一块空间,空间是4个char大小。内存空间如图所示,a指向了一块空间,有8个元素,每个元素的空间用来保存了一个char*的数据,也就是char的指针,a算是一个指向指针的指针。a是一个指针,指向了一块数据,这块数据保存的是一个指针,指向了一块数据,这块数据保存的是一个4字节的char。

 

 我们看一下实际的内存地址

 

这是char*数组a的数据,8个char*的空间,标蓝的是第一个a+0保存的数据,是一个指针地址,因为是32位的,所以是4个字节,翻译过来就是0X00557600

我们看一下a的第一块数据指向的内容,是一块数据,保存了aaaa,四个a。

 

这就是二维数组的实质。一维数组a指向了一块数据,保存的是字符,二维数组指向了一块数据,保存的相当于是一个一维数组指针的列表,每个二维数组元素相当于一个一维数组。以此类推,三维数组就是保存了一个二维数组指针的列表。

它是如何访问数据的呢,与一维数组一样,先通过a+i访问到a的元素指针,然后通过*(a+i)访问到数据,这个数据又是个数组,通过*(a+i)+j访问到元素指针,再通过*(*(a+i)+j)访问到数据,最后提醒,别忘了释放空间。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!