一 :关于指针和堆的内存分配
先来介绍一下指针 : 指针一种类型,理论上来说它包含其他变量的地址,因此有的书上也叫它:地址变量。既然指针是一个类型,是类型就有大小,在达内的服务器上或者普通的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()分配的,位于内存的堆区中,并且该对象未命名。
下面是关于new 操作的说明 : 部分引自>
1、new运算符返回的是一个指向所分配类型变量(对象)的指针。对所创建的变量或对象,都是通过该指针来间接操作的,而动态创建的对象本身没有名字。
2、一般定义变量和对象时要用标识符命名,称命名对象,而动态的称无名对象(请注意与栈区中的临时对象的区别,两者完全不同:生命期不同,操作方法不同,临时变量对程序员是透明的)。
3、堆区是不会在分配时做自动初始化的(包括清零),所以必须用初始化式(initializer)来显式初始化。new表达式的操作序列如下:从堆区分配对象,然后用括号中的值初始化该对象。
下面是从堆中申请数组
1、申请数组空间:
指针变量名=new 类型名[下标表达式];
注意:“下标表达式”不是常量表达式,即它的值不必在编译时确定,可以在运行时确定。这就是堆的一个非常显著的特点,有的时候程序员本身都不知道要申请能够多少内存的时候,堆就变的格外有用。
2、释放数组空间:
delete [ ]指向该数组的指针变量名;
注意:方括号非常重要的,如果delete语句中少了方括号,因编译器认为该指针是指向数组第一个元素的,会产生回收不彻底的问题(只回收了第一个元素所占空间),我们通常叫它“内存泄露”,加了方括号后就转化为指向数组的指针,回收整个数组。delete [ ]的方括号中不需要填数组元素数,系统自知。即使写了,编译器也忽略。>上说过以前的delete []方括号中是必须添加个数的,后来由于很容易出错,所以后来的版本就改进了这个缺陷。
下面是个例子,VC上编译通过
#include<iostream>
using namespace std;
//#include <iostream> //for VC
#include <string>
void main(){
int n;
char *p;
cout>n; //n在运行时确定,可输入17
p=new char[n]; //申请17个字符(可装8个汉字和一个结束符)的内存空间strcpy(pc,“堆内存的动态分配”);//
cout>n;
pc2=new CGoods[n];
//动态建立数组,不能初始化,调用n次缺省构造函数
……
delete pc;
delete pc1;
delete []pc2; }
申请堆空间之后构造函数运行;
释放堆空间之前析构函数运行;
再次强调:由堆区创建对象数组,只能调用缺省的构造函数,不能调用其他任何构造函数。如果没有缺省的构造函数,则不能创建对象数组。
---------------------下面我们再来看一下指针数组和数组指针―――――――――――――
如果你想了解指针最好理解以下的公式 :
(1)int*ptr;//指针所指向的类型是int
(2)char*ptr;//指针所指向的的类型是char
(3)int**ptr;//指针所指向的的类型是int* (也就是一个int * 型指针)
(4)int(*ptr)[3];//指针所指向的的类型是int()[3] //二维指针的声明
(1)指针数组:一个数组里存放的都是同一个类型的指针,通常我们把他叫做指针数组。
比如 int * a[10];它里边放了10个int * 型变量,由于它是一个数组,已经在栈区分配了10个(int * )的空间,也就是32位机上是40个byte,每个空间都可以存放一个int型变量的地址,这个时候你可以为这个数组的每一个元素初始化,在,或者单独做个循环去初始化它。
例子:
int * a[2]={ new int(3),new int(4) }; //在栈区里声明一个int * 数组,它的每一个元素都在堆区里申请了一个无名变量,并初始化他们为3和4,注意此种声明方式具有缺陷,VC下会报错
例如 :
int * a[2]={new int[3],new int[3]};
delete a[0];
delet a[10];
但是我不建议达内的学生这么写,可能会造成歧义,不是好的风格,并且在VC中会报错,应该写成如下 :
int * a[2];
a[0]= new int[3];
a[1]=new int[3];
delete a[0];
delet a[10];
这样申请内存的风格感觉比较符合大家的习惯;由于是数组,所以就不可以delete a;编译会出警告.delete 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]; //三级指针――>指向三维数组的指针;
int (*b2) [20]; //二级指针;
b3=new int [1] [20] [30];
b2=new int [30] [20];
两个数组都是由600个整数组成,前者是只有一个元素的三维数组,每个元素为30行20列的二维数组,而另一个是有30个元素的二维数组,每个元素为20个元素的一维数组。
删除这两个动态数组可用下式:
delete [] b3; //删除(释放)三维数组;
delete [] b2; //删除(释放)二维数组;
再次重申:这里的b2的类型是int (*) ,这样表示一个指向二维数组的指针。
b3表示一个指向(指向二维数组的指针)的指针,也就是三级指针.
( 3 ) 二级指针的指针
看下例 :
int (**p)[2]=new (int(*)[3])[2];</string></iostream></iostream>
分享到:
相关推荐
### 彻底理解指针,指针数组和数组指针,指针函数和函数指针 #### 一、基础知识 在计算机编程中,指针是一个非常重要的概念,尤其是在C/C++这样的语言中更是如此。简单来说,指针是一种变量,但它存储的不是普通的...
### 彻底了解指针数组、数组指针以及函数指针 #### 一、指针与内存分配 在C语言中,指针是一种非常重要的数据类型,它存储的是其他变量或对象的地址。掌握指针的基本概念对于深入理解C语言至关重要。本文将详细...
在这个例子中,我们看到如何使用函数指针以及多层函数指针数组。 首先,`Drive`函数接受三个参数:目标距离`_distance`、现有燃油`hasoil`和一个名为`engine`的函数指针。函数指针`engine`指向一个接受整型燃油`oil...
"C语言指针数组函数笔记" ...本笔记总结了C语言中的指针和数组相关知识点,涵盖了变量、指针变量、指针运算符、数组和指针数组函数等内容。通过阅读本笔记,读者可以更好地理解和应用C语言中的指针和数组。
标题中的“多线程函数指针数组.rar”表明这是一个关于多线程编程的资源,其中可能包含使用函数指针数组来实现线程间通信或任务调度的示例代码。描述中提到“很复杂,很复杂,值得研究,但不适合做游戏”,这暗示了多...
接下来是一个更复杂的示例,涉及到多级指针以及函数指针数组的使用: ```cpp char*(*(*pf)[3])(char *p); ``` 这段代码定义了一个多层嵌套的指针类型`pf`。这里`pf`是一个指向一个包含三个元素的数组的指针,每个...
通过将函数指针传递给其他函数,可以在这些函数内部调用我们传入的函数,这在设计模式和事件驱动编程中非常常见。 了解这些概念后,程序员可以更灵活地处理数据和控制程序流程,尤其是在编写系统级或底层代码时。...
C++指针数组内存释放 C++指针是一种基本变量,包含一个实际的数据,该数据代表一个可以找到实际信息的内存地址。指针是C++编程中非常重要的概念,许多程序和思想依靠指针作为他们设计的基础。 定义指针变量 定义...
本文将深入探讨“C++指针数组”的概念、用途以及相关操作。 一、指针与数组的基础知识 1. 指针:在C++中,指针是一个变量,它存储了另一个变量的地址。通过指针,我们可以间接访问和修改被指向的变量。指针的声明...
这个函数实现了冒泡排序算法的变体,但它不是直接比较和交换数组中的元素,而是通过比较和交换指针数组中的指针来达到排序的目的。具体步骤如下: 1. 外层循环控制排序的轮数。 2. 内层循环负责比较每一对相邻的...
"指针数组,将数组存放在堆中" 指针数组是一个非常重要的概念,在编程中,它可以用来存储大量的数据,并且可以灵活地进行操作。在本文中,我们将详细介绍指针数组的概念、声明方式、数组的创建、元素的访问、数组的...
C语言中对函数指针数组不是很了解,老师最近布置了一个作业,就搜集资料写了一个,希望能给大家启发,如果对C语言复杂指针的分析不是很懂得话,可以网上搜索“右左法则”
本文详细讲解了指针数组的使用方式以及其原理,及一些内存开辟函数的使用方法及原理。通过对指针数组的学习,我们需要了解指针及内存开辟函数。 首先,指针数组是指一个数组中每一个元素都是一个指针。例如,int *p...
在整个过程中,我们并没有移动字符串本身,只是改变了指针数组中指针的顺序,这是一种高效且灵活的处理方式。通过这种方式,我们可以在不复制大量字符的情况下完成字符串的排序,这对于处理大量数据尤其有用。 总结...
指针数组在C语言中的应用 在C语言中,指针数组是一种重要的数据结构,广泛应用于字符串处理、矩阵运算和动态存储管理等领域。本文将详细介绍指针数组的定义、使用和应用。 一、指针数组的定义 指针数组是一种特殊...
2. **段2**: 此段代码展示了如何使用 `print_char` 函数来打印字符指针数组中的内容。通过 `char *array[]` 定义了一个字符指针数组,并通过循环输出每个元素的内容。这里 `array++` 的操作使得 `array` 指向数组中...
本文将深入探讨函数指针数组的原理,以及如何利用它们来简化复杂的逻辑处理,提高代码的执行效率。 #### 函数指针的基础理解 在C语言中,函数名实际上是一个指针,它指向函数在内存中的起始地址。因此,我们可以像...
函数指针和函数指针数组 函数指针是一种特殊的指针,它是指向函数的指针。函数指针可以用来存放函数的地址,并且可以通过函数指针来调用函数。 1. 简单介绍 函数指针是指向函数的指针,它可以用来存放函数的地址...
指针是C++高效编程的关键工具,尤其是在处理大型数据结构、动态内存分配以及函数参数传递时。本篇将通过两个实例深入探讨指针与指针数组的应用。 首先,我们来看"指针.cpp"这个文件。在这个文件中,可能包含了一个...
在C语言中,指针是一种强大的工具,可以用来操作内存地址,实现对数据的高效访问。本主题将深入探讨如何使用指针...在实际开发中,指针数组常常用于内存管理、数据结构(如链表、树等)以及处理文件和I/O操作等场景。