当前位置:文档之家› 动态存储分配

动态存储分配

2018/10/11
13
说明以下定义的区别
a) int ival = 1024; b) int *pi = &ival; c) int *ip2 = new int(1024); d) int *ip3 = new int[1024];
2018/10/11
14
class Point { public: Point(); //难点
2018/10/11
23
#include "vector.h" int main() { int arr[5] = {1,2,3,4,5}; vector v1(arr,5),v2;
cout << "elems at index " << 3 << " : " << v1.at(3) << endl; cout << "length of v2 is : " << v2.len() << endl;
19
练习--设计一个整型的Vector类

设计一个动态的整型数组类Vector,它能根据用户提供 的参数动态生成元素,即
Vector v1;//生成包含0个元素的空数组 Vector v2(n); //生成包含n个元素的数组
Vector v2(n,m); //生成包含n个元素,每个元素值为m的数组
通过循环计算5点构成的折线长度

难点
如何为每个点生成满足题目范围的随机坐标值
如何实现用户敲击一次键盘,创建一个点?
2018/10/11

是否是:Point pt[5];?????????
8
程序的内存映象

试着思考:为什么定义数组的时候 下标必须是常量? int arr[10]; 为什么不能是:int m,int arr[m]; scanf(“%d”,&m); 一个已经编译完成的C程序取得并 使用4块在逻辑上不同并且用于不 同目的的内存区域。
18
double aver = 0; int x,y; cout << "---------------------------\n"; for(i = 0;i < 4; i++) { x = ptr[i] -> getX() - ptr[i + 1] -> getX(); y = ptr[i] -> getY() - ptr[i + 1] -> getY(); aver += sqrt(x * x + y * y); } cout << "折线总长度是:" << aver << endl; for(i = 0 ;i < 5; i++) { delete [] ptr[i]; } system("pause"); return 0;}
10


2018/10/11
动态存储分配

由动态内存管理系统管理的这块内存区域叫做 “堆(heap)”: 当需要动态灵活地分配内存空间时,需要用到动
态存储分配
动态分配得到的内存块位于堆中,且没有名字
动态存储分配由库函数malloc.h提供 格式:p = (double* ) malloc(n*sizeof(double)) C++中动态存储分配由运算符new和delete实现 new和delete完成动态存储分配时,可以很好 地和构造函数、析构函数进行交互,malloc和 free不能自行调用构造函数和析构函数 2018/10/11 11

用Point类描述位于第 一象限的点。用户敲 击一次ENTER键,程 序创建一个点,该点 的横纵、坐标值随机 ,并在[0,100]。敲击5 次以后,计算所有点 构成的折线总长度。
7
分析

思路
定义Point类,思考该类具有哪些成员
定义5个Point类的对象,调用成员函数分别获取每
个点的横、纵坐标值
}
2018/10/11
22
构造函数的初始化列表
vector::vector(int ilen,int *ielems) :length(ilen) { int i;
elems = new int[length]; for(i = 0 ; i < length; i++) elems[i] = ielems[i]; }//初始化列表只能出现在成员函数的定义中!!

具体声明格式: <类名>::<类名> (const <类名>& <对象名>) 复制构造函数只有一个参数,是该类对象的引用 若用户没有显式定义复制构造函数,编译器会自 动生成一个默认的复制构造函数,其功能是把已 知对象的每个数据成员都复制到新定义的对象中

2018/10/11
29
vector类的复制构造函数
主要内容
动态存储分配(难点) 程序在内存中的分布 new和delete运算符 复制构造函数——浅复制和深复制 析构函数 类的静态成员 分为静态数据成员和静态成员函数 静态数据成员如何初始化?是通过构造函数吗? 静态成员函数的定义和调用规则 多文件结构

2018/10/11
重点、难点
动态存储空间的分配

具体方法: 指针变量名 = new 类型;
指针变量名 = new 类型 (初值);
指针变量名 = new 类型 [元素个数]; 当执行new时,有两件事发生: 大小适当的空间被分配给特定类型的变量; 该存储空间首地址作为new表达式的返回值,若分
配失败则返回0 ;
vector::vector(const vector & v) { length = v.length; elems = new int[v.length]; for(i = 0 ; i < length; i++) elems[i] = v.GetElemsi[i]; }
2018/10/11
30

理解复制构造函数的作用及其调用时机,能正 确完成含有资源的对象复制 理解析构函数的作用和调用时机,能正确利用 析构函数完成对象相关资源的清理

能正确使用静态成员解决实际问题
2018/10/11
回顾--对象的初始化

对象在定义的时候对其数据成员进行初始化, 称为对象的初始化 C++中对象的初始化由一个特殊的成员函数 (构造函数)完成
16
Point::Point() { x = rand() % 101; y = rand() % 101; }
17
int main() { Point *ptr[5] = {NULL}; srand(time(NULL));
int i = 0; for( ;cin.get() == '\n' && i < 5; i++) { ptr[i] = new Point; ptr[i]->print(); }

5
对象的清理工作
对象的清理工作由析构函数完成 主要功能: 在对象生存周期即将结束的时刻,由编译系统自

动调用来完成一些清理工作 在程序块执行完最后一条语句后,系统自动调用 析构函数

语法格式为: <类名> :: ~<类名>() { <函数体> }
6
计算屏幕上若干点构成的折线长度

基本类型一般不采用动态存储分配
12
2018/10/11
动态存储空间的回收
用new分配的空间一定要用delete回收 具体使用格式: delete 指针变量名

delete[] 指针变量名 //用于动态数组的内存回收 delete只能用于回收new所分配的空间 对于一个指针指向的堆对象只能执行一次 delete操作 delete[]忽略括符内的具体数字,无论是几维数 组的空间回收均只用一个括符表示
return 0; }
2018/10/11
ቤተ መጻሕፍቲ ባይዱ
24
vector的析构函数
vector::~vector() { cout<<"对象正在析构…… " <<endl; delete [] elems;//回收指针elems所指堆内存 }
2018/10/11
25
几点说明

析构函数与类同名,无参数,无需指定返回值

21
序运行过程中,大小无法改变 动态数组在程序运行中,可根据需要重新指定大小 2018/10/11
vector::vector(int ilen,int *ielems) { int i;
length = ilen; elems = new int[length]; for(i = 0 ; i < length; i++) elems[i] = ielems[i];
析构函数不能有参数,因此不能重载
析构函数不能回收对象本身所占空间 如果不需要做清理工作,类可以没有析构函数 思考: 在vector中,对象v1和v2能不能正确析构?? 考虑对象的内存分布……
2018/10/11
26
对象的复制机制
v1 5 3050 1 2 3 4 5 堆对象 hello
2018/10/11

堆 静态存储区
程序区

2018/10/11
9
程序中变量的内存分配方式
相关主题