二维数组的动态分配与释放
C语言中多维数组的内存分配和释放(malloc与free)
C语言中多维数组的内存分配和释放(malloc与free)的方法
写代码的时候会碰到多维数组的内存分配和释放问题,在分配和释放过程中很容易出现错误。
下面贴上一些示例代码,以供参考。
如果要给二维数组(m*n)分配空间,代码可以写成下面:
(注意红色部分)
释放应该是:
如果为三维数组(m*n*p)分配空间呢,应该是:
释放代码为逆过程,具体代码为:
三维以上的多维数组的分配和释放,原理与上面的一样。
C中如何为第二维长度固定的二维数组分配内存
在所写的代码中,有时需要为一个二维数组分配内存,该二维数组的第一维长度不定,而第二维是固定(类似arr[n][3]的数组)。
我们可以想到的是用双指针代替数组,当然可以;也可以直接对n赋值后,直接定义arr[n][3] (C99标准支持),但这里要说的是另一种方法。
这里以将点云数据读入二维数组为例,由于点云点数n不定,可以确定的是,点是三维点,可以用以下方式定义并分配内存:
double (*arr)[3] = malloc (n*3*sizeof(double));
但在VC编译环境下,将会报错——无法从“void *”转换为“double (*)*3+” ,此时应该在malloc函数之前进行类型转换,应该如何转换呢?怎样转换才能成double (*)[3]类型呢,可以进行如下转换:
double (*arr)[3] = (double ((*)[3]))malloc (n*3*sizeof(double));。
最新C++二维动态数组的申请与_释放汇总
C++二维动态数组的申请与_释放一维数组是指针,可将二维数组看作是指针的指针:每一行是一个一维数组,而列是指向行的指针。
在动态创建时,先分配指向行的指针空间,再循环维每一行申请空间。
#include <iostream>using namespace std;int main(){//[3]4] //三行四列的二维数组int x,y;int i,n,k;x=3;y=4;int **p;p = new int*[x]; //行 //申请行的空间//每行的列申请空间for(i=0; i<x;i++){p[i] = new int [y];}//赋值,k=0;for(i=0;i<x;i++){for(n=0;n<y;n++){p[i][n] = k;k++;}}//显示刚才的赋值for(i=0;i<x;i++){for(n=0;n<y;n++){cout << p[i][n] << "\t"; }cout << endl;}//删除刚才申请的内存for(i=0;i<x;i++){delete [] p[i];}delete [] p;return 0;今天归纳总结了一下,希望以后的朋友可以少走些弯路:)一:关于指针和堆的内存分配先来介绍一下指针:指针一种类型,理论上来说它包含其他变量的地址,因此有的书上也叫它:地址变量。
既然指针是一个类型,是类型就有大小,在达内的服务器上或者普通的PC机上,都是4个字节大小,里边只是存储了一个变量的地址而已。
不管什么类型的指针,char * ,int * ,int (*) ,string * ,float * ,都是说明了本指针所指向的地址空间是什么类型而已,了解了这个基本上所有的问题都好象都变的合理了。
在C++中,申请和释放堆中分配的存贮空间,分别使用new和delete的两个运算符来完成:指针类型指针变量名=new 指针类型 (初始化);delete 指针名;例如:1、 int *p=new int(0);它与下列代码序列大体等价:2、int tmp=0, *p=&tmp;区别:p所指向的变量是由库操作符new()分配的,位于内存的堆区中,并且该对象未命名。
二维数组分配内存
C 二维数组动态分配和释放(1)已知第二维Code-1char (*a)[N];//指向数组的指针a = (char (*)[N])malloc(sizeof(char *) * m);printf("%d\n", sizeof(a));//4,指针printf("%d\n", sizeof(a[0]));//N,一维数组free(a);(2)已知第一维Code-2char* a[M];//指针的数组int i;for(i=0; i<M; i++)a[i] = (char *)malloc(sizeof(char) * n);printf("%d\n", sizeof(a));//4*M,指针数组printf("%d\n", sizeof(a[0]));//4,指针for(i=0; i<M; i++)free(a[i]);(3)已知第一维,一次分配内存(保证内存的连续性)Code-3char* a[M];//指针的数组int i;a[0] = (char *)malloc(sizeof(char) * M * n);for(i=1; i<M; i++)a[i] = a[i-1] + n;printf("%d\n", sizeof(a));//4*M,指针数组printf("%d\n", sizeof(a[0]));//4,指针free(a[0]);(4)两维都未知Code-4char **a;int i;a = (char **)malloc(sizeof(char *) * m);//分配指针数组for(i=0; i<m; i++){a[i] = (char *)malloc(sizeof(char) * n);//分配每个指针所指向的数组}printf("%d\n", sizeof(a));//4,指针printf("%d\n", sizeof(a[0]));//4,指针for(i=0; i<m; i++){free(a[i]);}free(a);(5)两维都未知,一次分配内存(保证内存的连续性)Code-5char **a;int i;a = (char **)malloc(sizeof(char *) * m);//分配指针数组a[0] = (char *)malloc(sizeof(char) * m * n);//一次性分配所有空间for(i=1; i<m; i++){a[i] = a[i-1] + n;}printf("%d\n", sizeof(a));//4,指针printf("%d\n", sizeof(a[0]));//4,指针free(a[0]);free(a);2.C++动态分配二维数组(1)已知第二维Code-6char (*a)[N];//指向数组的指针a = new char[m][N];printf("%d\n", sizeof(a));//4,指针printf("%d\n", sizeof(a[0]));//N,一维数组delete[] a;(2)已知第一维Code-7char* a[M];//指针的数组for(int i=0; i<M; i++)a[i] = new char[n];printf("%d\n", sizeof(a));//4*M,指针数组printf("%d\n", sizeof(a[0]));//4,指针for(i=0; i<M; i++)delete[] a[i];(3)已知第一维,一次分配内存(保证内存的连续性)Code-8char* a[M];//指针的数组a[0] = new char[M*n];for(int i=1; i<M; i++)a[i] = a[i-1] + n;printf("%d\n", sizeof(a));//4*M,指针数组printf("%d\n", sizeof(a[0]));//4,指针delete[] a[0];(4)两维都未知Code-9char **a;a = new char* [m];//分配指针数组for(int i=0; i<m; i++){a[i] = new char[n];//分配每个指针所指向的数组}printf("%d\n", sizeof(a));//4,指针printf("%d\n", sizeof(a[0]));//4,指针for(i=0; i<m; i++)delete[] a[i];delete[] a;(5)两维都未知,一次分配内存(保证内存的连续性)Code-10char **a;a = new char* [m];a[0] = new char[m * n];//一次性分配所有空间for(int i=1; i<m; i++){a[i] = a[i-1] + n;//分配每个指针所指向的数组}printf("%d\n", sizeof(a));//4,指针printf("%d\n", sizeof(a[0]));//4,指针delete[] a[0];delete[] a;多说一句:new和delete要注意配对使用,即有多少个new就有多少个delete,这样才可以避免内存泄漏!3.静态二维数组作为函数参数传递如果采用上述几种方法动态分配二维数组,那么将对应的数据类型作为函数参数就可以了。
c语言 申请二维数组
在C语言中,你可以使用以下几种方式来申请一个二维数组:1. 静态二维数组:在声明时就分配内存。
```cint arr[3][4]; // 声明一个3x4的二维数组```2. 动态二维数组:使用`malloc`或`calloc`函数在运行时分配内存。
```cint arr;int rows = 3;int cols = 4;arr = malloc(rows * sizeof(int *)); // 为行指针分配内存for(int i=0; i<rows; i++) {arr[i] = malloc(cols * sizeof(int)); // 为每一行的元素分配内存}```3. 使用指针和指向指针的指针:这是动态分配二维数组的一种更复杂的方式。
```cint rows = 3;int cols = 4;int arr = malloc(rows * sizeof(int *)); // 声明行指针数组for(int i=0; i<rows; i++) {arr[i] = malloc(cols * sizeof(int)); // 为每一行分配内存}```4. 使用固定大小的数组:如果你知道数组的大小是固定的,你可以直接使用静态数组。
但如果你需要动态改变大小,那么你需要使用动态内存分配。
5. 使用结构体:如果你需要存储更复杂的数据,例如不仅有数值还有字符串或其它结构,你可以使用结构体。
6. 使用标准库中的二维数组类型:在某些编译器或库中,可能提供二维数组类型,这使得处理二维数据更加方便。
但是,C语言标准并没有提供这样的类型。
当你不再需要这些数组时,记得释放分配的内存,以避免内存泄漏。
对于动态分配的二维数组,首先释放每一行的内存,然后再释放行指针的内存。
C语言中动态分配二维数组
}
for(i=0;i<n1;i++)
{
for(j=0;j<n2;j++)
{
for(k=0;k<n3;k++)
free(array[i][j][k]);//释放第四维指针
}
}
for(i=0;i<n1;i++)
{
for(j=0;j<n2;j++)
{
free(array[i][j]);//释放第三维指针
}
} array[][][](整型常量)
当然,你可以把它们整合在一起为:
int i,j,k;
int n1,n2,n3;
int ***array;
scanf("%d%d%d",&n1,&n2,&n3);
array=(int***)calloc(n1,sizeof(int**));
for(i=0;i<n1;i++)
for(k=0;k<n3;k++)
{
array[i][j][k]=i+j+k+1;
printf("%d\t",array[i][j][k]);
}
puts("");
}
puts("");
}
for(i=0;i<n1;i++)
{
for(j=0;j<n2;j++)
{
free(array[i][j]);//释放第三维指针
如何解决C C 中stack overflow问题
如何解决C/C++中stack overflow问题一般遇到这个问题,有两个常见的情况,一个是存在函数的递归调用,另一个是函数中定义了一个较大的数组或者别的变量。
1、在函数的递归调用中,函数中定义的局部变量所占的空间要直到递归结束才能被释放,这样函数不停的递归,堆栈早晚会被用完,解决这一问题的办法是在递归函数中每次动态的分配变量的内存,在使用结束的时候释放内存。
遇到这种情况更改堆栈的最大空间大小是没有用的,要从代码的优化入手。
下面以二维数组的动态分配为例:p=new double*[1000];for (int m=0;m<1000;m++){p[m]=new double[5000];}for(int n=0;n<1000;n++) {delete[] p[n];} delete[] p;2、堆栈的大小只有1M,如果在函数中定义了一个占用内存比较大的变量,那么也会导致堆栈溢出。
这种情况只需在定义的时候定义为静态变量就行了,因为静态变量是不占用堆栈内存的。
如:void main(){int;}在函数内定义的变量默认auto类型,也就是栈变量,运行时使用的是栈空间,函数结束后自动清理返回内存。
这里在函数内定义如此大的一个数组,已经超过了单个函数可使用的最大栈空间,所以也会提示stack overflow。
解决办法是将其定义为static int型的静态变量,这样就不占用栈空间了。
void main(){static int}3、除此之外还可以通过修改堆栈的最大空间来解决问题,把project设置里的堆栈加大就可以了,默认是1M,你可以加大到10M试试. 具体如下:。
对于遇到这样的问题建议从代码方面去解决,不要盲目的依靠修改堆栈空间来解决,毕竟有的问题靠修改空间是解决不了的,如递归中产生的stack overflow。
数组的动态分配特点
数组的动态分配特点
1. 大小灵活:动态分配数组的大小可以根据需要动态调整,不受静态数组的固定大小限制。
这样就可以根据需求动态地调整数组的大小,提高内存的利用率。
2. 内存管理灵活:动态分配数组的内存分配和释放由程序员手动管理,可以根据实际情况在需要的时候申请内存,并在不需要的时候释放内存,从而提高内存的利用效率。
3. 动态扩展:动态分配数组可以进行动态扩展,即在原来的数组基础上扩展新的空间。
这样可以方便地添加新的元素,并避免了静态数组需要重新定义大小的麻烦。
4. 灵活访问:动态分配数组可以通过索引随机访问数组中的元素,可以根据索引值直接访问数组中的元素,提高了数据的读取效率。
5. 灵活修改:动态分配数组可以根据需要随时修改数组中的元素,可以修改数组中的元素的值,方便处理和管理数据。
C 二维动态数组的申请与_释放
一维数组是指针,可将二维数组看作是指针的指针:每一行是一个一维数组,而列是指向行的指针。
在动态创建时,先分配指向行的指针空间,再循环维每一行申请空间。
#include <iostream>using namespace std;int main(){//[3]4] //三行四列的二维数组int x,y;int i,n,k;x=3;y=4;int **p;p = new int*[x]; //行 //申请行的空间//每行的列申请空间for(i=0; i<x;i++){p[i] = new int [y];}//赋值,k=0;for(i=0;i<x;i++){for(n=0;n<y;n++){p[i][n] = k;k++;}}//显示刚才的赋值for(i=0;i<x;i++){for(n=0;n<y;n++){cout << p[i][n] << "\t";}cout << endl;}//删除刚才申请的内存for(i=0;i<x;i++){delete [] p[i];}delete [] p;return 0;今天归纳总结了一下,希望以后的朋友可以少走些弯路:)一:关于指针和堆的内存分配先来介绍一下指针:指针一种类型,理论上来说它包含其他变量的地址,因此有的书上也叫它:地址变量。
既然指针是一个类型,是类型就有大小,在达内的服务器上或者普通的PC机上,都是4个字节大小,里边只是存储了一个变量的地址而已。
不管什么类型的指针,char * ,int * ,int (*) ,string * ,float * ,都是说明了本指针所指向的地址空间是什么类型而已,了解了这个基本上所有的问题都好象都变的合理了。
在C++中,申请和释放堆中分配的存贮空间,分别使用new和delete的两个运算符来完成:指针类型指针变量名=new 指针类型 (初始化);delete 指针名;例如:1、 int *p=new int(0);它与下列代码序列大体等价:2、int tmp=0, *p=&tmp;区别:p所指向的变量是由库操作符new()分配的,位于内存的堆区中,并且该对象未命名。
C语言中二维数组的动态申请与释放
C语⾔中⼆维数组的动态申请与释放有时根据题意需得根据输⼊的⼆维数来动态的创建⼆维数组,那么此时就不能想以前⼀样直接定义多少⾏多少列了。
因为不知道⾏列多少,假如设定太⼤浪费空间,申请太⼩完成不了程序的数据存储。
因此需要合理的开辟⼆维空间。
以下的两种⽅法都可以建⽴动态的⼆维空间数组。
⽅法⼀:int i,j;int r,c;int **a; //创建⼆维指针来指向数组scanf("%d%d",&r,&c);a = (int **) malloc(sizeof(int *) * r);//注意申请的指针格式for (j=0;j<r;j++){a[j] = (int *) malloc(sizeof(int) * c);…………}释放为:for (j=0;j<r;j++)free(a[j]);//先释放⼀维指针free(a);//最后释放我⼆维指针⽅法⼆:建⽴链表来存放⼆维数组。
typedef struct arr{int *array;}arr;main(){arr *array1;int rowx,rowy;int i,j,k=0;scanf("%d %d",&rowx,&rowy);array1=(arr *)malloc(sizeof(arr)*rowx);//创建链表数组for(i=0;i<rowx;i++)//再在每⼀个链表中创建⼀维数组,这样整体就构成⼆维数组array1[i].array=(int *)malloc(sizeof(int)*rowy);…………释放同上:for (j=0;j<rowx;j++)free(array1[j].array);free(array);}。
C++二维动态数组的申请与_释放
一维数组是指针,可将二维数组看作是指针的指针:每一行是一个一维数组,而列是指向行的指针。
在动态创建时,先分配指向行的指针空间,再循环维每一行申请空间。
#include <iostream>using namespace std;int main(){//[3]4] //三行四列的二维数组int x,y;int i,n,k;x=3;y=4;int **p;p = new int*[x]; //行 //申请行的空间//每行的列申请空间for(i=0; i<x;i++){p[i] = new int [y];}//赋值,k=0;for(i=0;i<x;i++){for(n=0;n<y;n++){p[i][n] = k;k++;}}//显示刚才的赋值for(i=0;i<x;i++){for(n=0;n<y;n++){cout << p[i][n] << "\t";}cout << endl;}//删除刚才申请的内存for(i=0;i<x;i++){delete [] p[i];}delete [] p;return 0;今天归纳总结了一下,希望以后的朋友可以少走些弯路:)一:关于指针和堆的内存分配先来介绍一下指针:指针一种类型,理论上来说它包含其他变量的地址,因此有的书上也叫它:地址变量。
既然指针是一个类型,是类型就有大小,在达内的服务器上或者普通的PC机上,都是4个字节大小,里边只是存储了一个变量的地址而已。
不管什么类型的指针,char * ,int * ,int (*) ,string * ,float * ,都是说明了本指针所指向的地址空间是什么类型而已,了解了这个基本上所有的问题都好象都变的合理了。
在C++中,申请和释放堆中分配的存贮空间,分别使用new和delete的两个运算符来完成:指针类型指针变量名=new 指针类型 (初始化);delete 指针名;例如:1、 int *p=new int(0);它与下列代码序列大体等价:2、int tmp=0, *p=&tmp;区别:p所指向的变量是由库操作符new()分配的,位于内存的堆区中,并且该对象未命名。
C++中二维数组的动态分配
C++中二维数组的动态分配C++中一维数组的动态分配十分常用,但C++初学者可能很少想过要使用动态分配的二维数组,或者自认为二维数组就是这样分配的(至少我自己开始的时候就这样认为):int m=2, n=3; int**array2D=new int[m][n];。
这完全是我们写多了像int n=4; int* array=new int[n];这样的语句留下的后遗症,纯粹是因为惯性太大刹都刹不住,就像某同学学完“一二三”要写“万”一样。
事实往往不是这么简单,看下面的正确方法就知道了:#include <iostream>using std::cout;using std::endl;int main() {int i, j;int m=2, n=3;//分配行指针数组int** array2D=new int*[m];//为每一行分配空间for(i=0; i<m; ++i) {array2D[i]=new int[n];}//可以稍微测试一下for(i=0; i<m; ++i) {for(j=0; j<n; ++j) {array2D[i][j]=i+j;}}for(i=0; i<m; ++i) {for(j=0; j<n; ++j) {cout<<array2D[i][j]<<"\t";}cout<<endl;}//删除每一行分配的空间for(i=0; i<m; ++i) {delete[] array2D[i];}//删除行指针数组delete[] array2D;return EXIT_SUCCESS;}利用C++二维数组动态分配的特点,我们还可以分配出用静态数组无法实现的不等长二维数组,想要多少就分配多少。
看下面的例子:#include <iostream>using std::cin;using std::cout;using std::endl;int main() {int i, j;int m=3;int n[3]={1, 2, 3};//行指针数组int** array2D=new int*[m];//每行分配不一样多的空间for(i=0; i<m; ++i) {array2D[i]=new int[n[i]];}//测试一下for(i=0; i<m; ++i) {for(j=0; j<n[i]; ++j) {array2D[i][j]=j+1;}}for(i=0; i<m; ++i) {for(j=0; j<n[i]; ++j) {cout<<array2D[i][j]<<"\t";}cout<<endl;}//删除分配的空间for(i=0; i<m; ++i) {delete[] array2D[i];}delete[] array2D;return EXIT_SUCCESS;}当然,如果你想一劳永逸,不想这么麻烦的分配来分配去,那么去写个类模板吧,在类模板中重载数组下标运算符,你就可以像使用静态数组一样使用你的类了。
c二维动态数组的申请与释放
一维数组是指针,可将二维数组看作是指针的指针:每一行是一个一维数组,而列是指向行的指针。
在动态创建时,先分配指向行的指针空间,再循环维每一行申请空间。
#include <iostream>using namespace std;int main(){delete pc; elete a[1];注意这里是一个数组,不能delete [] ;(2)数组指针:一个指向一维或者多维数组的指针;int * b=new int[10]; 指向一维数组的指针b ;注意,这个时候释放空间一定要delete [] ,否则会造成内存泄露, b 就成为了空悬指针.int (*b2)[10]=new int[10][10]; 注意,这里的b2指向了一个二维int型数组的首地址.注意:在这里,b2等效于二维数组名,但没有指出其边界,即最高维的元素数量,但是它的最低维数的元素数量必须要指定!就像指向字符的指针,即等效一个字符串,不要把指向字符的指针说成指向字符串的指针。
这与数组的嵌套定义相一致。
int(*b3) [30] [20];( 3 )二级指针的指针看下例 :int (**p)[2]=new (int(*)[3])[2];p[0]=new int[2][2];p[1]=new int[2][2];p[2]=new int[2][2];delete [] p[0];delete [] p[1];delete [] p[2];delete [] p;注意此地方的指针类型为int (*),碰到这种问题就把外边的[2]先去掉,然后回头先把int ** p=new int(*)[n]申请出来,然后再把外边的[2]附加上去;p代表了一个指向二级指针的指针,在它申请空间的时候要注意指针的类型,那就是int (*)代表二级指针,而int (**)顾名思义就是代表指向二级指针的指针了。
既然是指针要在堆里申请空间,那首先要定义它的范围:(int(*)[n])[2],n 个这样的二级指针,其中的每一个二级指针的最低维是2个元素.(因为要确定一个二级指针的话,它的最低维数是必须指定的,上边已经提到)。
c++二维数组的定义与使用
c++二维数组的定义与使用C++中的二维数组是一种特殊的数组,其元素包含多个值,可以看作是一个表格或者矩阵。
定义二维数组的语法如下:```cpptype arrayName[rows][columns];```其中,type代表数组元素的数据类型,arrayName是数组的名称,rows和columns分别表示二维数组的行数和列数。
例如,定义一个3行4列的整型二维数组:```cppint myArray[3][4];```可以使用嵌套循环来访问和操作二维数组的元素。
例如,可以使用两个循环来遍历二维数组的所有元素:```cppfor(int i = 0; i < 3; i++) {for(int j = 0; j < 4; j++) {// 访问二维数组的元素cout << myArray[i][j] << " ";}cout << endl;}```这样就可以依次访问二维数组的每个元素,并输出其值。
二维数组的元素可以使用索引来访问和修改。
索引的范围是从0到行数-1和列数-1。
例如,要访问myArray的第2行第3列的元素,可以使用myArray[1][2]。
注意,二维数组的元素在内存中是按照行优先的顺序存储的,即相邻的元素具有相邻的内存地址。
在C++中,也可以使用动态内存分配来创建二维数组。
例如,可以使用new运算符动态地创建一个3行4列的整型二维数组:```cppint** myArray = new int*[3];for(int i = 0; i < 3; i++) {myArray[i] = new int[4];}```要释放动态分配的二维数组的内存,需要使用delete运算符,先释放每一行的内存,再释放数组的内存。
总结起来,定义和使用C++中的二维数组可以使用静态数组或者动态分配的方式,通过嵌套循环可以对二维数组进行遍历和操作。
定义二维数组的三种方式
定义二维数组的三种方式
在编程中,可以使用以下三种方式定义二维数组:
1. 方式一:使用固定大小的二维数组
在这种方式中,我们直接声明一个具有固定行数和列数的二维数组,并为其分配内存空间。
语法如下:
数据类型[行数][列数] 数组名;
示例:
int[][] array = new int[3][4];
这将创建一个具有3行4列的整数类型的二维数组。
2. 方式二:使用动态分配的二维数组
在这种方式中,我们首先声明一个一维数组,然后为每个元素分配一个新的一维数组,形成二维数组。
语法如下:
数据类型[][] 数组名 = new 数据类型[行数][];
数组名[行索引] = new 数据类型[列数];
示例:
int[][] array = new int[3][];
array[0] = new int[4];
array[1] = new int[3];
array[2] = new int[2];
这将创建一个不规则的二维数组,每行的列数可以不同。
3. 方式三:使用初始化列表的二维数组
在这种方式中,我们直接使用初始化列表为二维数组赋值。
语法如下:
数据类型[][] 数组名 = {{元素1, 元素2, ...}, {元素1, 元素2, ...}, ...};
示例:
int[][] array = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
这将创建一个具有3行3列的整数类型的二维数组,并将相应的元素赋值。
以上是三种常见的定义二维数组的方式,根据具体的需
求和编程语言的规范,可以选择适合的方式进行定义和使用。
C语言动态分配二维数组内存
C语⾔动态分配⼆维数组内存C语⾔内存管理主要包括malloc()、remalloc()、free()三个函数。
malloc原型 extern void *malloc(unsigned int num_bytes);m⾏n列的⼆维数组的分配,主要有三种⽅法:⼀、分配⼀个长度为m的⼆级指针,指针的指向的内容分别指向⼀个长度为n的⼀位数组#include<stdio.h>#include<stdlib.h>#include<string.h>#include<math.h>//⼆维数组内存分配int main(){int i,j,c=0;int m,n;int **p;int *head;scanf("%d %d",&m,&n);p=(int **)malloc(sizeof(int *)*m);if (p==NULL){puts("memory allocation error!");return;}//head=(int *)p+m; //指向数据内容起始的⾸地址//memset(p,0,sizeof(int *)*m+sizeof(int)*m*n); //内存区域清零for (i=0;i<m;i++){//p[i]=head+(i*n); //both is ok*(p+i)=(int *)malloc(sizeof(int)*n);}for(i=0;i<m;i++){for (j=0;j<n;j++){*(*(p+i)+j)=c++;}}for(i=0;i<m;i++){for (j=0;j<n;j++){printf("%x: %4d\t",&p[i][j],p[i][j]);}printf("\n");}for (i=0;i<m;i++){free(p[i]);}free(p);system("pause");return0;}View Code⼆、分配⼀个长度为m*n的⼀级指针(即⼀维数组),通过地址转换来模拟⼆维数组的⾏为代码较简单,略去三、分配⼀个长度为m+m*n的⼆级指针,前m个地址分别存放后m*n个地址中每⾏的⾸地址#include<stdio.h>#include<stdlib.h>#include<string.h>//⼆维数组内存分配int main(){int i,j,c=0; // i,j为下标,c为赋初值⽅便int m,n; // m⾏ n列int **p;int *head;scanf("%d %d",&m,&n);p=(int **)malloc(sizeof(int *)*m+sizeof(int)*m*n);if (p==NULL){puts("memory allocation error!");return;}head=(int *)p+m; //指向数据内容起始的⾸地址,注意地址转换memset(p,0,sizeof(int *)*m+sizeof(int)*m*n); //内存区域清零for (i=0;i<m;i++){//p[i]=head+(i*n); //both is ok*(p+i)=head+(i*n);}for(i=0;i<m;i++){for (j=0;j<n;j++){*(*(p+i)+j)=c++;}}for(i=0;i<m;i++){for (j=0;j<n;j++){printf("%x: %4d\t",&p[i][j],p[i][j]);}printf("\n");}free(p);system("pause");return0;}第⼀种⽅法需要分配m+1次内存,释放时也要先分别释放⼀级指针,再释放⼆级指针;第三种⽅法分配连续的(m*n+m)*sizeof(int)个内存空间,操作较快。
二维数组的动态分配
⼆维数组的动态分配⼀维数组分配⽐较简单,在此略过。
但是平时经常遇到需要动态分配⼆维数组的情况。
下⾯给出⼏种⼆维数组分配⽅式。
注:⼆维数组⾏坐标、列坐标都是通过m,n来传递的。
1. 利⽤⼀维数组分配⽅式,模拟⼆维数组其实栈上⼆维数组仍然是个连续的内存空间,只不过在访问时做了相应的处理。
那么,动态分配时,也可分配⼀块连续的内存空间。
访问时通过(d + i m + j )访问即可。
int m =6, n =3;char*d =(char*)malloc(sizeof(int)* m * n );for(int i =0; i<m;++i ){for(int j =0; j<n;++j ){*(d + i*m + n )= i + j;cout <<static_cast<int>(*(d + i*m + n ))<<"\t";}cout << endl;}2. 利⽤STL vector实现动态⼆维数组STL中vector是基于固定长度数组的延伸,那么利⽤这种⽅法也可以得到动态⼆维数组。
具体⽅法见代码。
int m =6, n =3;vector<vector<int>> d( m,vector<int>( n,0));for(int i =0; i<m;++i ){for(int j =0; j<n;++j ){d[i][j]= i + j;cout <<static_cast<int>( d[i][j])<<"\t";}cout << endl;}3. 层层递进分配法此⽅法参考了:直接复制代码:char** allocateCharacterBoard(size_t xDimension,size_t yDimension){char** myArray =new char*[xDimension];// Allocate first dimensionfor(size_t i =0; i < xDimension; i++){myArray[i]=new char[yDimension];// Allocate ith subarray}return myArray;}void releaseCharacterBoard(char** myArray,size_t xDimension){for(size_t i =0; i < xDimension; i++){delete[] myArray[i];// Delete ith subarray}delete[] myArray;// Delete first dimension}上⾯总结的三种⽅法是我现在觉得⽐较好的⽅法,如果你有更好的⽅法,欢迎留⾔讨论。
二维数组指针及二维动态数组的分配问题
⼆维数组指针及⼆维动态数组的分配问题在我以前的⽂章中都有讲过关于数组指针及指针数组的相关问题,但是讲得不够深⼊,我后来后了别⼈写的博客后觉得⼈家的确实写得好,也学到了不少东西,对以前的问题有深的领悟了,于是准备结合这些博客和⽂章再稍微深⼊⼀点讲讲这些问题。
这些指针的问题是C语⾔中的基础与关键⽽且⼀旦出现这些问题,不太好找bug的来源,有时候不得不借助反汇编。
参考⽂章:C语⾔指针数组和数组指针如何在C/C++中动态分配⼆维数组现在我们知道了指针数组与数组指针的区别了嘛。
int *p1[10]; (1)这个就是指针数了啊,我们主要是看运算符的优先级,因为[ ] 的优先级⽐ * 的优先级要⾼,于是知p1⾸先和[10]结合-----p1[10]表⽰的是含有10个元素的数组,那么数组中元素类型呢?那就是 int * 也就是说 p1 是含有10元素为 int* 的数组名,注意p1是数组名⽽⾮什么指针。
int (*p2)[10]; (2)⽽现在就不同了,我们的(*p2)说明p2是指针,⽽不再像是(1)中的类型名了,嗯好,这个 * 是专门⽤来修饰p2的。
同样【10】表⽰含有10个元素啦,⽽int表⽰这个数组⾥⾯的内容是int 型。
则知道我们这个数组是没有数组名的。
其实(2)式组合起来说明p2是⼀个指针,但不是⼀个⼀般的指针,⽽是⼀个指向含有10个int型的数组的指针。
那有⼈问?这个p2指针和(3)int* p (3)中的p(普通的int型指针)有区别吗?当然是有区别的!不然这不是脱了裤头放屁-----多此⼀举。
搞得⼤家对(2)式不太理解。
分析代码:int a[4]={1,2,3,4};int (*pp)[4]=&a;std::cout<<pp[0];这个输出int a[4]={1,2,3,4};int (*pp)[4]=&a;std::cout<<pp[0][0];这个输出int a[4]={1,2,3,4};int (*pp)[4]=&a;std::cout<<*(pp+1);这个输出其实这个数组针⼀般是⽤在⼆维数组中的,因为如果我们声明int (*pp)[4]则我们对pp++;那么pp指针移动的可不只是⼀个int型的长度呢,那可是sizeof(int)*4的长度哦。
动态内存分配(new)和释放(delete)
动态内存分配(new)和释放(delete)在之前我们所写过的程序中,所必需的内存空间的⼤⼩都是在程序执⾏之前就已经确定了。
但如果我们需要内存⼤⼩为⼀个变量,其数值只有在程序运⾏时 (runtime)才能确定,例如有些情况下我们需要根据⽤户输⼊来决定必需的内存空间,那么该怎么办呢?答案是动态内存分配(dynamic memory),为此C++ 集成了操作符new和delete。
1. new 和 new [] 操作符动态内存分配⽤操作符new。
new 后⾯跟⼀个数据类型,如果要求的元素多于⼀个,需要加上[],元素数量放在 [] 中。
它返回⼀个指向内存块开始位置的指针。
语法是:pointer = new typepointer = new type [number_of_elements]第⼀个表达式为数据类型为 ‘type’ 的⼀个元素分配内存地址。
第⼆个表达式为数据类型为 ‘type’ 的⼀组元素分配⼀块内存,其中 number_of_elements 是整数型,表⽰元素的个数。
例如:int* foo;foo = new int[5];在这个例⼦⾥,操作系统分配了可存储5个整型int元素的内存空间,返回指向这块空间开始位置的指针并将它赋给foo。
因此,现在foo 指向⼀块可存储5个整型元素的合法的内存空间,如下图所⽰。
这⾥,foo 是⼀个指针,foo指向的第⼀个元素可以通过语句 foo[0] 或 *foo 得到,两者是等价的。
第⼆个元素可以通过语句 foo[1] 或 *(foo+1)得到,依次类推......那么刚才所作的给指针分配内存空间与定义⼀个普通的数组有什么不同呢?最重要的不同是,⼀个普通数组的长度必须是⼀个常量,这就将它的⼤⼩在程序执⾏之前就被决定了。
⽽采⽤动态内存分配时,数组的长度可以常量或变量,其值可以在程序执⾏过程中再确定。
动态内存分配通常由操作系统控制,在多任务的环境中,它可以被多个应⽤(applications)共享,因此内存有可能被⽤光。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
二维数组的动态分配与释放
1. C语言动态分配二维数组
(1)已知第二维
Code-1
char (*a)[N];//指向数组的指针
a = (char (*)[N])malloc(sizeof(char) * M*N); //注意M为数组的行,N为数组的列printf("%d\n", sizeof(a));//4,指针
printf("%d\n", sizeof(a[0]));//N*sizeof(char),一维数组
free(a);
(2)已知第一维
Code-2
char* a[M];//指针的数组
int i;
for(i=0; i<M; i++)
a[i] = (char *)malloc(sizeof(char) * n);
printf("%d\n", sizeof(a));//4*M,指针数组
printf("%d\n", sizeof(a[0]));//4,指针
for(i=0; i<M; i++)
free(a[i]);
(3)已知第一维,一次分配内存(保证内存的连续性)
Code-3
char* a[M];//指针的数组
int i;
a[0] = (char *)malloc(sizeof(char) * M * n);
for(i=1; i<M; i++)
a[i] = a[i-1] + n;
printf("%d\n", sizeof(a));//4*M,指针数组
printf("%d\n", sizeof(a[0]));//4,指针
free(a[0]);
(4)两维都未知
Code-4
char **a;
int i;
a = (char **)malloc(sizeof(char *) * m);//分配指针数组
for(i=0; i<m; i++)
{
a[i] = (char *)malloc(sizeof(char) * n);//分配每个指针所指向的数组
}
printf("%d\n", sizeof(a));//4,指针
printf("%d\n", sizeof(a[0]));//4,指针
for(i=0; i<m; i++)
{
free(a[i]);
}
free(a);
(5)两维都未知,一次分配内存(保证内存的连续性)
Code-5
char **a;
int i;
a = (char **)malloc(sizeof(char *) * m);//分配指针数组
a[0] = (char *)malloc(sizeof(char) * m * n);//一次性分配所有空间for(i=1; i<m; i++) //定义每个指针指向的空间大小
{
a[i] = a[i-1] + n;
}
printf("%d\n", sizeof(a));//4,指针
printf("%d\n", sizeof(a[0]));//4,指针
free(a[0]); //只需要释放a[0]
free(a);
2.C++动态分配二维数组
(1)已知第二维
Code-6
char (*a)[N];//指向数组的指针
a = new char[m][N];
printf("%d\n", sizeof(a));//4,指针
printf("%d\n", sizeof(a[0]));//N,一维数组
delete[] a;
(2)已知第一维
Code-7
char* a[M];//指针的数组
for(int i=0; i<M; i++)
a[i] = new char[n];
printf("%d\n", sizeof(a));//4*M,指针数组
printf("%d\n", sizeof(a[0]));//4,指针
for(i=0; i<M; i++)
delete[] a[i];
(3)已知第一维,一次分配内存(保证内存的连续性)
Code-8
char* a[M];//指针的数组
a[0] = new char[M*n];
for(int i=1; i<M; i++)
a[i] = a[i-1] + n;
printf("%d\n", sizeof(a));//4*M,指针数组
printf("%d\n", sizeof(a[0]));//4,指针
delete[] a[0];
(4)两维都未知
Code-9
char **a;
a = new char* [m];//分配指针数组
for(int i=0; i<m; i++)
{
a[i] = new char[n];//分配每个指针所指向的数组
}
printf("%d\n", sizeof(a));//4,指针
printf("%d\n", sizeof(a[0]));//4,指针
for(i=0; i<m; i++)
delete[] a[i];
delete[] a;
(5)两维都未知,一次分配内存(保证内存的连续性)
Code-10
char **a;
a = new char* [m];
a[0] = new char[m * n];//一次性分配所有空间
for(int i=1; i<m; i++)
{
a[i] = a[i-1] + n;//分配每个指针所指向的数组
}
printf("%d\n", sizeof(a));//4,指针
printf("%d\n", sizeof(a[0]));//4,指针
delete[] a[0];
delete[] a;
多说一句:new和delete要注意配对使用,即有多少个new就有多少个delete,这样才可以避免内存泄漏!。