一个简单的关于指针类型的内存空间的问题

  • 赵永康  2009-06-30 16:39

    现在还是对指针存有很多疑问,今天在网上看"C++从零开始",在指针这一章节有这么一段代码:

     unsigned long *pA = new unsigned long;
     *pA = 10;
     unsigned long *pB = new unsigned long[*pA];

    文章是这样解释的:"上面就申请了两块内存,pA所指的内存(即pA的值所对应的内存)是4字节大小,而pB所指的内存是    4*10=40字节大小。"

    其中,pA所指的内存是4字节大小我能理解,可是为什么pB所指的内存是40字节大小啊?这个怎么解释啊?

    我在机子上运行了下

    #include
    using namespace std;

    int main()
    {
        unsigned long *pA = new unsigned long;
        *pA = 10;
        unsigned long *pB = new unsigned long[*pA];

        cout << sizeof(*pA) << endl;
        cout << sizeof(*pB) << endl;

        delete pA;
        pA = NULL;
        delete []pB;
        pB = NULL;

        cout << sizeof(*pA) << endl;
        cout << sizeof(*pB) << endl;

        cin.get();
        return 0;
    }

    运行结果sizeof(*pA)和sizeof(*pB)都是4,是我错了还是网上这位作者错了

    然后就是释放内存,大家看一下我的代码,我觉的没有错误啊,可是为什么释放后,我这里运行

    的结果还都是4,这代表*pA和*pB没有释放吧, 为什么呢?

  • 赵永康
    #1
    赵永康  2009-06-30 16:46
    补充一下:
    释放前和释放后,pA和pB所存的内容变了
    释放前:
    pA = 009132D0
    pB = 009132E0
    释放后:
    pA = 00000000
    pB = 00000000

    我就是对这两个释放后内存大小都是4不太理解,我感觉应该是0或NULL
  • 普罗通信西安有限公司 肖舸(C/C++老师)<img src=/image/teacher.gif border=0>
    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的指针使用*求值,是严重违反犯罪行为,呵呵。
  • 重庆邮电大学 吴小伟(C/C++学生)
    *pB 取得的是new出来的数组的第一个元素, 所以*pB对应的大小是unsigned long的大小。pB所指向的内存空间确实有(*pA)  *  sizeof(unsigned long)这么大。。。但通过sizeof(*pB)就只能得出这个数组的第一个元素的内存大小,所以你得到的是4,而不是你网上看到的40.

    至于释放内存后,sizeof(*pA) 中进行*pA运算应该就是一个缺陷,这个行为应该是未定义的。
  • 赵永康
    #4
    赵永康  2009-07-01 08:16
    重庆邮电大学 吴小伟(C/C++学生): *pB 取得的是new出来的数组的第一个元素, 所以*pB对应的大小是unsigned long的大小。pB所指向的内存空间确实有(*pA)  *  sizeof(unsigned long)这么大。。。但通
    厉害,看来我得加把劲儿了,还望以后多多指教,呵呵
  • 赵永康
    #5
    赵永康  2009-07-01 08:18
    普罗通信西安有限公司 肖舸(C/C++老师)teacher.gif: 1、pA和pB都是指向无符号长整形的数字的指针,因此,*pA和*pB就是无符号长整形数字,这在32位操作系统下,位宽为4Bytes因此,你的运行结果却是是4,程序结果是对的。
    2、
    uns
    原来是这么回事啊,肖老师解释的真是精辟,看来我还得在指针上多下点工夫,我还是想问肖老师一个比较低级的问题,我怎么样才能把指针学好呢?再好好学习一下内存的知识吗?
  • 普罗通信西安有限公司 肖舸(C/C++老师)<img src=/image/teacher.gif border=0>
    河北师范大学/中北信号软件 赵永康(C/C++学生): 原来是这么回事啊,肖老师解释的真是精辟,看来我还得在指针上多下点工夫,我还是想问肖老师一个比较低级的问题,我怎么样才能把指针学好呢?再好好学习一下内存的知
    学好指针的最好方法:能不用就不用。
  • 福州大学 小枫(C/C++学生)
    #7
    福州大学 小枫(C/C++学生)  2009-07-01 10:55
    普罗通信西安有限公司 肖舸(C/C++老师)teacher.gif: 学好指针的最好方法:能不用就不用。
    指针很强大 我最喜欢了
  • 福州大学 小枫(C/C++学生)
    #8
    福州大学 小枫(C/C++学生)  2009-07-01 11:07
    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]
  • 赵永康
    #9
    赵永康  2009-07-01 14:07
    福州大学 小枫(C/C++学生): unsigned long A[10];
    A的空间是静态开辟的,A是不能改变的(不能做左值),sizeof(A)的值是40了。
    你的代码:
    unsigned long *pB = new unsigned long[10];
    pB数组时动
    A的空间是静态开辟的,pB是动态开辟的,是不是因为pB是指针所以它是动态开辟的啊
    小枫能不能指点一下怎么样把指针学好学精
    听肖老师说"能不用就不用",可是我感觉C++里涉及到指针的地方很多啊,不太理解高人的想法,呵呵
  • 赵永康
    #10
    赵永康  2009-07-01 14:09
    普罗通信西安有限公司 肖舸(C/C++老师)teacher.gif: 学好指针的最好方法:能不用就不用。
    肖老师,恕我愚钝,能不能给学生解释一下,呵呵
    您的这句话是不是用指针的一种境界啊
  • 普罗通信西安有限公司 肖舸(C/C++老师)<img src=/image/teacher.gif border=0>
    河北师范大学/中北信号软件 赵永康(C/C++学生): 肖老师,恕我愚钝,能不能给学生解释一下,呵呵
    您的这句话是不是用指针的一种境界啊
    指针太灵活,容易造成的bug太多。因此,我的原则是尽量不用。
    像本文的例子,完全可以不用指针的,当然,为了练习,这么写也对,因此,我只是建议,不要为了用指针而用指针。
  • 福州大学 小枫(C/C++学生)
    #13
    福州大学 小枫(C/C++学生)  2009-07-01 19:32
    type *p = new type[N]; 这样形式的都是动态开辟的。
    C如果学的差不多了建议看《C和指针》《C专家编程》,学指针关键是要理解它
  • 赵永康
    #14
    赵永康  2009-07-02 08:24
    广西师范大学 曹磊宇(Net学生): 貌似 学好 汇编 对指针的理解很到位
    有道理,谢谢,呵呵
  • 代码人生(C/C++爱好者)
    #15
    代码人生(C/C++爱好者)  2009-07-02 16:12
    去看看C和指针这本书吧。指针灵活度相当的高,用的不好就是一种破坏,用的好让你事半功倍。
  • 徐名峰(数据库老师)<img src=/image/teacher.gif border=0>
    #16
    徐名峰(数据库老师)teacher.gif  2009-07-03 00:31
    指针是不可不用的,以前曾和某人争论,说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;"里面的*的已经有不同的含义.这其实也是指针容易让大家迷惑的地方.
  • 赵永康
    #17
    赵永康  2009-07-03 08:12
    徐名峰(数据库老师)teacher.gif: 指针是不可不用的,以前曾和某人争论,说java里面也有指针,某人不认可,说java一大优点就是消灭了指针,并让我定义一个指针出来,我回答道:
    如果你声明一个对象,在new
    9.gif有种相见恨晚的感觉,以后多向徐老师学习,谢谢了
    我再多做些联系感受一下指针
  • 赵永康
    #18
    赵永康  2009-07-03 08:14
    代码人生(C/C++爱好者): 去看看C和指针这本书吧。指针灵活度相当的高,用的不好就是一种破坏,用的好让你事半功倍。
    好的,我找找这本书,谢谢

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/16856446/viewspace-611865/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/16856446/viewspace-611865/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值