使用malloc在堆上创建二维数组

来源:互联网 发布:abaqus软件介绍 编辑:程序博客网 时间:2024/06/08 09:52

先回顾new在堆上分配内存,见我的博文点击打开链接 C/C++的数据类型判断的最后总结的:如果new后边的类型是非数组类型,那么返回的类型是这种类型的指针(最内层的指针,是其本质);如果new后边的类型是数组,那么返回的类型是数组退化为指针之后的类型。关于退化,见我的博文点击打开链接中关于C/C++赋值中的退化规则。

malloc的返回值是void* 类型的泛型指针,需要强制类型转换为其它指针类型来赋值。

分配连续的内存给二维数组:

    int rows = 10;    int columns = 5;    int  *p[10];    //p是指针数组  数组在三中情况之外都相当于指针常量    int **matrix = p;        matrix[0] = (int*)malloc(rows*columns*sizeof(int));    for (int i = 1; i < rows; ++i)    {        matrix[i] = matrix[0] + i*columns;    }
或者这样,跟要求连续空间的二维数组保持一致:

int rows = 10;int columns = 5;int **matrix = (int**)malloc(rows*sizeof(int*));matrix[0] = (int*)malloc(rows*columns*sizeof(int));for (int i = 1; i < rows; ++i){matrix[i] = matrix[0] + i*columns;cout << matrix[i] << endl;}

需要注意的是,这里一定要有p这个数组,而不能简单的定义一个指针变量

int *p;int **matrix = &p;  

原因是matrx[1] , matrix[2]...都发生了越界,他们都不是定义的变量的地址(指针),不能去改写。


分配非要求连续空间的二维数组:

int rows = 10;int columns = 5;int** matrix = (int**)malloc(rows*sizeof(int*));   //在堆上构建一个中间数组,中间数组的每个元素来管理一行    for (int i = 0; i < rows; ++i)    {        matrix[i] = (int*)malloc(columns*sizeof(int));    }
或者像上边一样,管理的一个一维数组在栈上:

        int rows = 10;int columns = 5;int *p[10];int ** matrix = p;for (int i = 0; i < rows; ++i){p[i] = (int*)malloc(columns*sizeof(int));}

可以看到无论哪种方式,都需要借助一个中间层数组来管理。于是可以看到C++中new 操作符的强大优势,分配二维数组,直接new int [10][5],   简单不容易出错, hiahia.

二维数组若是退化,会退化为数组指针,C/C++中的数组本身是按行优先的线性存储,二维数组名是指向第0行的数组指针,终极的写法如下:

typedef int(*Arr)[5];Arr p = (Arr)malloc(sizeof(int)* 10 * 5);  //p是数组指针,指向的一维的维数是5                                                  //malloc分配的是连续的线性空间  一共有10个这样的一维数组

其实无论怎样,最终都需要malloc() 出 sizeof(int)*rows*columns这么多空间 ,无论是一维,二维,还是三维数组,最终都是线型的存储在内存中,问题的关键在于能不能通过matrix[i][j] 这样形式,使用下标能够正确的索引。

常见的错误写法如下:

int rows = 10;int columns = 5;int** matrix = (int**)malloc(rows*columns*sizeof(int));for (int i = 1; i < rows; ++i){matrix[i] = matrix[0] + i*columns;}matrix[9][9] = 0;

这里的matrix[0]是分配空间的最开始四个字节,由于matrx的类型是int**,所以这四个字节此时被当做int*来解释了,不过由于这四个字节的内容未知,这就是错误的根源!



0 0
原创粉丝点击