赵永康 2009-06-30 16:39 现在还是对指针存有很多疑问,今天在网上看"C++从零开始",在指针这一章节有这么一段代码: unsigned long *pA = new unsigned long; 文章是这样解释的:"上面就申请了两块内存,pA所指的内存(即pA的值所对应的内存)是4字节大小,而pB所指的内存是 4*10=40字节大小。" 其中,pA所指的内存是4字节大小我能理解,可是为什么pB所指的内存是40字节大小啊?这个怎么解释啊? 我在机子上运行了下 #include int main() cout << sizeof(*pA) << endl; delete pA; cout << sizeof(*pA) << endl; cin.get(); 运行结果sizeof(*pA)和sizeof(*pB)都是4,是我错了还是网上这位作者错了 然后就是释放内存,大家看一下我的代码,我觉的没有错误啊,可是为什么释放后,我这里运行 的结果还都是4,这代表*pA和*pB没有释放吧, 为什么呢? |
补充一下: 释放前和释放后,pA和pB所存的内容变了 释放前: pA = 009132D0 pB = 009132E0 释放后: pA = 00000000 pB = 00000000 我就是对这两个释放后内存大小都是4不太理解,我感觉应该是0或NULL |
1、pA和pB都是指向无符号长整形的数字的指针,因此,*pA和*pB就是无符号长整形数字,这在32位操作系统下,位宽为4Bytes因此,你的运行结果却是是4,程序结果是对的。 2、 unsigned long *pA = new unsigned long; *pA = 10; unsigned long *pB = new unsigned long[*pA]; 第一句你创建了一个无符号长整形变量,仅仅是你没有给这个变量命名,而是为其指针命名了。 第二句更简单,变量赋值。 第三句,是创建一根指针,指向一个无符号长整形的数组,这个数组的宽度呢,是10,这里,pA没什么事情,主要是携带了数组长度。 我们知道,无符号长整形数字的位宽是4Bytes,10个单元,自然40Bytes啦。 3、还有个特性你还没说呢,pB++,这个算式是成立的,不过,这加一次,就是加一个无符号长整形的位宽,也就是4Bytes,因此,C和C++里面,++到底是加多少,其实是不一定的,看变量类型来。 4、你的程序,合理地释放了pA和pB,没有错误,但最后的sizeof有点危险,对一个明知道为null的指针使用*求值,是严重违反犯罪行为,呵呵。 |
*pB 取得的是new出来的数组的第一个元素, 所以*pB对应的大小是unsigned long的大小。pB所指向的内存空间确实有(*pA) * sizeof(unsigned long)这么大。。。但通过sizeof(*pB)就只能得出这个数组的第一个元素的内存大小,所以你得到的是4,而不是你网上看到的40. 至于释放内存后,sizeof(*pA) 中进行*pA运算应该就是一个缺陷,这个行为应该是未定义的。 |
厉害,看来我得加把劲儿了,还望以后多多指教,呵呵 |
原来是这么回事啊,肖老师解释的真是精辟,看来我还得在指针上多下点工夫,我还是想问肖老师一个比较低级的问题,我怎么样才能把指针学好呢?再好好学习一下内存的知识吗? |
学好指针的最好方法:能不用就不用。 |
指针很强大 我最喜欢了 |
unsigned long A[10]; A的空间是静态开辟的,A是不能改变的(不能做左值),sizeof(A)的值是40了。 你的代码: unsigned long *pB = new unsigned long[10]; pB数组时动态开辟的空间,pB最开始代表的只是数组的首地址, pB本身也是动态的,如,*pB==pB[0],*(++pB)==pB[1] |
A的空间是静态开辟的,pB是动态开辟的,是不是因为pB是指针所以它是动态开辟的啊 小枫能不能指点一下怎么样把指针学好学精 听肖老师说"能不用就不用",可是我感觉C++里涉及到指针的地方很多啊,不太理解高人的想法,呵呵 |
肖老师,恕我愚钝,能不能给学生解释一下,呵呵 您的这句话是不是用指针的一种境界啊 |
指针太灵活,容易造成的bug太多。因此,我的原则是尽量不用。 像本文的例子,完全可以不用指针的,当然,为了练习,这么写也对,因此,我只是建议,不要为了用指针而用指针。 |
貌似 学好 汇编 对指针的理解很到位 |
type *p = new type[N]; 这样形式的都是动态开辟的。 C如果学的差不多了建议看《C和指针》《C专家编程》,学指针关键是要理解它 |
有道理,谢谢,呵呵 |
去看看C和指针这本书吧。指针灵活度相当的高,用的不好就是一种破坏,用的好让你事半功倍。 |
指针是不可不用的,以前曾和某人争论,说java里面也有指针,某人不认可,说java一大优点就是消灭了指针,并让我定义一个指针出来,我回答道: 如果你声明一个对象,在new之前就访问成员变量或方法,系统一定会给你报出异常,什么异常呢,null point exception,看到指针了没有,java 里处处皆为指针,干脆省去了那个*.省去了*,也省去了很多麻烦,只能是一重指针,二重,三重就没法搞了. 其实,指针没像你们说的那么复杂,你只要记好一句话,指针是存放地址的空间,就够了,二重指针呢,存放一重指针(刚才说了,是个空间)的地址的空间,依此类推...,一个指针只能存一个地址,也就是说只能指向一个字节,有人说不是,用*一次可以取出多个字节,那是因为指针有了类型,没有类型的指针不能用*, unsigned long *pB = new unsigned long[10]; 声明了一个unsigned long 类型的指针pB,同时开辟了10个unsigned long 类型的变量(非指针空间),并把第一个变量的地址放入pB. 你这里面有一个麻烦的问题就是sizeof(*pB),这已经不是指针的问题,而是sizeof编译器是如何处理的,在sizeof里*的含义已经不是指向的意思了,就像 "int *a;"和"*a=3;"里面的*的已经有不同的含义.这其实也是指针容易让大家迷惑的地方. |
有种相见恨晚的感觉,以后多向徐老师学习,谢谢了我再多做些联系感受一下指针 |
好的,我找找这本书,谢谢 |
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/16856446/viewspace-611865/ ,如需转载,请注明出处,否则将追究法律责任。