#includevoid update_p_ref(int * intp) { int temp = 1; intp = &temp; printf("up_r_p=%pn", intp); printf("up_r_v=%dn", *intp); //temp variable "temp" will be collected } //transfer parameters as reference void update_p_ref2(int*& intp_ref) { int temp = 3; intp_ref = &temp; printf("up_rr_p=%pn", intp_ref); printf("up_rr_v=%dn", *intp_ref); } void update_p_ref3(int& int_ref) { int_ref = 5; printf("up_rr_p=%pn", &int_ref); printf("up_rr_v=%dn", int_ref); } void update_p_value(int* intp) { *intp = 2; printf("up_v_p=%pn", intp); printf("up_v_v=%dn", *intp); } //transfer parameters as reference void update_p_value2(int*& intp_ref) { *intp_ref = 4; printf("up_vr_p=%pn", intp_ref); printf("up_vr_v=%dn", *intp_ref); } void update_p_value3(int& int_ref) { int_ref = 6; printf("up_vr_p=%pn", &int_ref); printf("up_vr_v=%dn", int_ref); } int main() { int* p = nullptr; // declare pointer and initialize it // so that it doesn't store a random address int i = 0; p = &i; // assign pointer to address of object int j = *p; // dereference p to retrieve the value at its address printf("p=%pn", p); printf("p_v=%dn", *p); printf("--------transfer parameters pointer as value normally-------n"); update_p_ref(p); printf("p1=%pn", p); printf("p1_v=%dn", *p); update_p_value(p); printf("p2=%pn", p); printf("p2_v=%dn", *p); printf("--------transfer parameters pointer as reference-------n"); p = &i; update_p_ref2(p); printf("p3=%pn", p); printf("p3_v=%dn", *p); update_p_value2(p); printf("p4=%pn", p); printf("p4_v=%dn", *p); printf("--------above code generate a dangling pointer "p" ,%s%s", "because temporary variable "3"(in update_p_ref2) and "5"(in update_p_value2)", "'s dynamically allocated memory has been freed with foo stack quitting------- n"); p = new int(0); printf("p_ad=%pn", p); printf("p_v_ad=%dn", *p); delete(p);//p is a vild pointer now printf("p_ad2=%pn", p); p = NULL;//or p=nullptr printf("p_ad3=%pn", p); printf("--------transfer parameters value as reference-------n"); p = &i; update_p_ref3(*p); printf("p5=%pn", p); printf("p5_v=%dn", *p); update_p_value3(*p); printf("p6=%pn", p); printf("p6_v=%dn", *p); }
(win10-64位 *** 作系统下运行,分别编译目标平台为win32和x64)输出结果如下,自行体会:
个人总结几个基础点:
①指针指向数据值所在的地址(或者说,当指针的值是地址时,它指向内存中的数据);
②&:寻址符(其后为一个左值——要区别于表达式),对左值寻址获得指针变量,指针变量引用内存地址中的数据;
③*:取值符(其后为一个指针变量),对指针变量取消指针引用,获得指针变量引用的内存地址中的数据;
④对于不是通过关键字new进行内存分配的指针,使用delete释放内存会报错,原因是delete只能释放在堆(heap)中分配的内存空间;其他方式如通过&寻址左值(内存分配在当前作用域的栈中)获取的指针,会在当前堆栈(stack)退出(})时自动释放。
C/C++定义了4个内存区间:代码区,全局变量与静态变量区,局部变量区即栈区,动态存储区,即堆(heap)区或自由存储区(free store)
⑤另外的,造成野指针的几个主要原因:指针变量未初始化;指针释放后之后未置空(p_ad2);指针 *** 作超越变量作用域(p3_v、p4_v)。
⑥悬空指针(p3_v、p4_v,个人认为此处是野指针,待考究)。
———————————————以下来自wiki—————————————
在计算机科学中,指针是一种引用。
原始数据(或仅仅是原始)是可以被读取或写入任何数据的计算机存储器使用一个存储器存取(例如,两者字节和一个字是原语)。
数据集合体(或只是聚合)是一组是原语的逻辑在存储器中连续和被作为一个数据集中观察(例如,聚集体可以是3个逻辑上连续的字节,其值表示的3个坐标空间中的点)。当一个聚合完全由相同类型的基元组成时,该聚合可以称为数组;从某种意义上说,多字节字原语是一个字节数组,有些程序就是这样使用字的。
在这些定义的上下文中,字节是最小的原语;每个内存地址指定一个不同的字节。数据的起始字节的内存地址被认为是整个数据的内存地址(或基本内存地址)。
存储器指针(或只是指针)是原始的,它的值旨在被用作存储器地址; 据说一个指针指向一个内存地址。也有人说,当指针的值是数据的内存地址时,指针指向数据[在内存中]。
更一般地说,指针是一种引用,据说指针引用了存储在内存某处的数据;获得该数据就是取消对指针的引用。将指针与其他类型的引用区分开来的特点是,指针的值被解释为内存地址,这是一个相当低级的概念。
引用作为一个间接级别:指针的值确定在计算中使用哪个内存地址(即哪个数据)。因为间接性是算法的一个基本方面,指针在编程语言中通常表示为一种基本数据类型;在静态(或强)类型编程语言,该类型的指针的判定基准,以该指针指向的类型。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)