C++中int a[10]和int* a=new int[10]]有什么区别

我们常常看见,在图论中,对一个Graph类在初始化的时候,对类的成员变量**arc(邻接矩阵,是一个二维数组,大小是顶点数*顶点数,存储内容为边的权值,而且矩阵的对角线元素均为0),有如下的初始化方法:

//构造函数
Graph_DG::Graph_DG(int vexnum, int edge) {
	//初始化顶点数和边数
	this->vexnum = vexnum;
	this->edge = edge;
	//为邻接矩阵开辟空间和赋初值
	arc = new int*[this->vexnum];
	dis = new Dis[this->vexnum];
	for (int i = 0; i < this->vexnum; i++) {
		arc[i] = new int[this->vexnum];
		for (int k = 0; k < this->vexnum; k++) {
			//邻接矩阵初始化为无穷大
			arc[i][k] = INT_MAX;
		}
	}
}

首先arc是一个二级指针,为arc分配this->vexnum空间,每一维都是一个指向数组的指针,且每个数组内部的地址空间是连续的,但是数组之间的地址空间没有连续性。

注意,动态分配内存后的值是一个不定值,而并非0。

这种分配方法在内存中的布局:

C++中int a[10]和int* a=new int[10]]有什么区别_第1张图片

参考代码

#include 
using namespace std;

int main()
{
	int **arc;
	int x = 5;
	int y = 5;
	arc = new int*[x];
	for (int i = 0; i < y; i++)
	{
		arc[i] = new int[y];
	}
	for (int i = 0; i < x; i++)
		for (int j = 0; j < y; j++)
			cout << arc[i][j] << endl;
	cout << "--------------------------------------------------------" << endl;
	for (int i = 0; i < x; i++)
		for (int j = 0; j < y; j++)
			cout << &(arc[i][j]) << endl;
	system("pause");
	return 0;
}

输出结果:

C++中int a[10]和int* a=new int[10]]有什么区别_第2张图片


#include 
using namespace std;

int main()
{
	int *arc;
	int x = 5;
	arc = new int[x];
	for (int i = 0; i < x; i++)
		cout << arc[i] << endl;
	cout << "--------------------------------------------------------" << endl;
	for (int i = 0; i < x; i++)
		cout << &(arc[i]) << endl;
	system("pause");
	return 0;
}

C++中int a[10]和int* a=new int[10]]有什么区别_第3张图片

注意,同一个new出来的是连续内存,new一个一维数组确实是连续内存,但多个new出来的就不是连续内存了。

凡是new出来的都是建立在堆上,不管是不是连续内存。也就是说,堆上建立的,不一定是不连续内存。


基础知识

我们先说一说int a[10]和int* a=new int[10]]。

        1、int a[10]使用简单,系统会自动实现内存的分配和回收。int* a=new int[10]需要判断内存是否分配成功,以及在不用时需要使用delete[] a进行内存释放,否则会造成;
  2、如果不是a[10],而是a[1000000000]或者更大的话,那一般情况下,就只能使用int* a=new这种方式了。这个涉及到内存存放位置的问题,int a[]这种方式,内存是存放在栈上;int* a=new这种方式,内存是存放在堆上栈的实际内存是连续内存,因此可分配空间较小,堆可以是非连续内存,因此可以分配较大内存。因此,如果需要分配较大内存,需要分配在堆上;(注意,同一个new出来的是连续内存,new一个一维数组确实是连续内存,但多个new出来的就不是连续内存了。

  3、使用int a[10]这种方式,内存大小需要用常量指定,比如这里的10。不能用int m=10;int a[m]这种方式。但是int* a= new这种方式可以,因此在动态分配内存上,后者有非常大的优势。


双重指针

我们先看下代码:

#include  
using namespace std; 

int main() {
    int p = 10; 
    int *ptr = &p; 

    cout << "p的值:" << p 
         << endl; 
    cout << "p的内存地址: " << &p 
         << endl;
    cout << "*ptr指示的值: " << *ptr 
         << endl; 
 
    cout << "ptr的值: " << ptr 
         << endl; 
    cout << "ptr的内存地址: " << &ptr 
         << endl; 
    system("pause");
    return 0; 
}

输出结果如下:

C++中int a[10]和int* a=new int[10]]有什么区别_第4张图片

一般的整型指针定义是int* ptr=&p,表示int* ptr,初始化了一个整型的指针ptr,然后ptr=&p,即将ptr指向了p所在的地址,所以ptr的值就是内存地址,而*ptr的值就是取出ptr表示的内存地址中的内容,所以*ptr=p。而&ptr必然就是p的地址了,这就涉及到了双重指针。

双重指针就是指针的指针,简称双指针,如果在上面的代码中,我们要存储ptr的内存地址,就必须定义一个int** ptr2=&ptr。

你可能感兴趣的:(C++)