另一方面,对于地址为1.32位的操作系统,地址均为32位,前0是不可省略的示例: int *p=NULL; coutpendl; 输出00000000而不是//02。 指针可以直接从存储器地址访问数据,从而避免将大量代码复制到程序中。 因此,指针效率最高例子: a[j]:a j
a[i][j]:a[i] j
二、内存1 .内存中数据的存储格式1 )堆栈空间:编译器自动分配和释放
一般存储函数的参数值、局部变量的值等
2 )堆)程序员分配、释放。 程序员不释放时,程序结束后操作系统可能会回收
3 )寄存器区)容纳栈顶指针和指令指针
4 )全局区域(静态区域) :全局变量和静态变量保存在一起。 已初始化的和未初始化的是分开的。
程序结束后系统释放
5 )字符常数区域)程序结束后,系统释放
保存常数字符串
6 )程序代码区域)存储函数体的二进制代码
2 .堆和堆栈之间的区别:
堆栈申请方式程序员必须自行申请,申请时指定申请大小,系统自行分配系统响应方式。 浏览内存空闲地址链表,找到比申请更大的堆节点,将其
中申请的大小被分配给程序,程序空间被放入可用链表中
如果堆栈的剩馀空间不足,overflow的最大空间大小由系统中的有效虚拟内存决定,2M运行效率慢,容易出现内存碎片,灵活性高,没有内存碎片
补充:
)1)指针具有保护内存数据的作用
堆栈可以命名其内存单元之一,但堆中的每个内存单元都是匿名的。 这是数据保护。 必须向堆申请内存单元地址,然后保存到指针。 只有这个指针才能访问该存储器单元的数据。
)2) delete运算符只能删除堆中的空间。 删除堆栈中的区域将导致错误
int main () {A a; a * p=新a; A *q=a; delete p; //正确,因为p是指堆内的未命名空间delete q; //错误,因为q指向堆栈中的空间返回0; } 3.内存泄漏(1)指向指针所在的堆节点,未释放class A{}; int main () {A *p=new A; 未释放返回0 }
)2)指针是局部变量,在释放内存之前由于远离范围而导致class A{}消失的void Test () {A *p=new A; }无法释放}int main (() return 0; }
)3)父类中指一个子类的对象,析构函数为多态性class A{} ); class B:public A{int x; (; void Test () {A *p=new A; (}int main ) ) {A *p=new B; //只释放基类占用的空间,x占用的空间不释放delete p; 返回0; }
三、堆1 .访问堆成员的两种方法
有两种方法可以访问堆成员。 A *p=new A (;
1 () p ).get ); 2 ) p-get
示例:
class A{int x; 公共: a (inti ) :x(i ) {}int get ) {返回x; }; int main () a*p=newa ) 1、) q=newa ) 2; cout(p ).get ) ) ' ' q-get ) endl; 返回0; (输出:1) 2
四.堆栈1 .函数调用时的堆栈和外栈顺序:堆栈顺序:1)被调用函数的下一行地址2 )自变量(从右到左)3)函数的全局变量
出场的顺序相反。
2 .堆栈中的对象遇到“}”时的自动语法分析示例: class A{public:~A () {cout '语法分析' endl; }; Void测试() ) a; }int main () {Test ); 返回0; }
输出:析构函数