二维数组定义以及动态分配空间

来源:互联网 发布:it基础知识培训 编辑:程序博客网 时间:2024/06/05 00:35

一、下面三种定义形式怎么理解?怎么动态分配空间?
(1)、int**Ptr;
(2)、int*Ptr[5];我更喜欢写成int*Prt[5];
(3)、int(*Ptr)[5];
二、意义:
(1)、int**Ptr表示指向"一群"指向整数的指针的指针。
(2)、int*Ptr[5]指针数组,该数组有5个元素,每个元素都是一个指向整型的指针(即一个地址)
(3)、int(*Ptr)[5]数组指针。
三、所占空间:
(1)、int**Ptr和(3)、int(*Ptr)[5]一样,在32位平台里,都是4字节,即一个指针。但(2)、int*Ptr[5]不同,它是5个指针,它占5*4=20个字节的内存空间。
四、用法:
(1)、int**Ptr因为是指针的指针,需要两次内存分配才能使用其最终内容。首先,Ptr=(int**)newint*[5];这样分配好了以后,它和(2)的意义相同了;然后要分别对5个指针进行内存分配,例如:Ptr[0]=newint[20];它表示为第0个指针分配20个整数,分配好以后,Ptr[0]为指向20个整数的数组。这时可以使用下标用法Ptr[0][0]到
Ptr[0][19]了。如果没有第一次内存分配,该Ptr是个"野"指针,是不能使用的,如果没有第二次内存分配,则Ptr[0]等也是个"野"指针,也是不能用的。当然,用它指向某个已经定义的地址则是允许的,那是另外的用法(类似于"借鸡生蛋"的做法),这里不作讨论(下同)。

例子:

C语言:

//动态分配二维数组空间
{
m_iHight=10;//二维数组的高度
m_i;//二维数组的宽度
//动态分配一个二维数组m_ppTable内存空间
//其类型为int
//m_ppTable指向该数组
int**m_ppTable;
m_ppTable=newint*[m_iHight];

//动态分配m_iHight个类型为int*的内存空间
//分配的是行地址空间
for(inti=0;i
m_ppTable[i]=newint[m_iWidth];

//动态分配m_iWidth个类型为int的内存空间
//分配的是某行的数值空间
}
//由此分配的二维数组空间并非是连续的
//可以使用m_ppTable[row][col]来给该二维数组赋值
//其中0<=row
//释放所分配的内存空间
{
for(inti=0;i
delete[m_iWidth]m_ppTable[i];//以行为单位释放数值空间
delete[m_iHight]m_ppTable;//释放行地址空间
}

int**a;
a=(int**)calloc(sizeof(int*),n);
for(i=0;ia[i]=(int*)calloc(sizeof(int),n);//这样就可以了,使用的时候就和普通的二维数组一样,最后用
for(i=0;icfree(a[i]);
cfree(a);//释放内存就可以了
(2)、int*Ptr[5]这样定义的话,编译器已经为它分配了5个指针的空间,这相当于(1)中的第一次内存分配。根据对(1)的讨论可知,显然要对其进行一次内存分配的。否则就是"野"指针。
(3)、int(*Ptr)[5]这种定义我觉得很费解,不是不懂,而是觉得理解起来特别吃力,也许是我不太习惯这样的定义吧。怎么描述它呢?它的意义是"一群"指针,每个指针都是指向一个5个整数的数组。如果想分配k个指针,
这样写:Ptr=(int(*)[5])newint[5*k]。这是一次性的内存分配。分配好以后,Ptr指向一片连续的地址空间,
其中Ptr[0]指向第0个5个整数数组的首地址,Ptr[1]指向第1个5个整数数组的首地址。
综上所述,我觉得可以这样理解它们:
int**Ptr&lt;==>intPtr[x][y];
int*Ptr[5]<==>intPtr[5][x];
int(*Ptr)[5]<==>intPtr[x][5];
这里x和y是表示若干的意思。

_______________________________________________________________

1.C语言动态分配二维数组

(1)已知第二维

Code-1

char(*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-2

char*a[M];//指针的数组

inti;

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];//指针的数组

inti;

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;

inti;

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;

inti;

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-6

char(*a)[N];//指向数组的指针

a=newchar[m][N];

printf("%d\n",sizeof(a));//4,指针

printf("%d\n",sizeof(a[0]));//N,一维数组

delete[]a;

(2)已知第一维

Code-7

char*a[M];//指针的数组

for(inti=0;i<M;i++)

a[i]=newchar[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]=newchar[M*n];

for(inti=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=newchar*[m];//分配指针数组

for(inti=0;i<m;i++)

{

a[i]=newchar[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=newchar*[m];

a[0]=newchar[m*n];//一次性分配所有空间

for(inti=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.静态二维数组作为函数参数传递

如果采用上述几种方法动态分配二维数组,那么将对应的数据类型作为函数参数就可以了。这里讨论静态二维数组作为函数参数传递,即按照以下的调用方式:

inta[2][3];

func(a);

C语言中将静态二维数组作为参数传递比较麻烦,一般需要指明第二维的长度,如果不给定第二维长度,则只能先将其作为一维指针传递,然后利用二维数组的线性存储特性,在函数体内转化为对指定元素的访问。

首先写好测试代码,以验证参数传递的正确性:

(1)给定第二维长度

Code-11

voidfunc(inta[][N])

{

printf("%d\n",a[1][2]);

}

(2)不给定第二维长度

Code-12

voidfunc(int*a)

{

printf("%d\n",a[1*N+2]);//计算元素位置

}

注意:使用该函数时需要将二维数组首地址强制转换为一维指针,即func((int*)a);


原文地址:http://blog.sina.com.cn/s/blog_726ddb650100o023.html