none
指针函数的问题! RRS feed

  • 问题

  • double* treble(double data)
    {
     double result = 0.0;
     result = 3.0 * data;
     return &result;
    }

    我在书上看到一个示例的一个函数是这样的
    书上说这个函数在编译的时候会弹出一条警告而且这个函数返回的值我用一个指针变量接受后打印出来是一个数字和字母组成的不知道什么的乱东西!!
    因为变量result是在函数执行的时候被创建 函数结束的时候就消息了 所以一开始result变量的地址就被其他数据所占用了 所以得不到真正想要的结果

    但是不知道为什么 在我的机器上这个函数竟然正确运行 而且返回正确结果 !!我很是郁闷 不知道怎么回事 大伙们你们试试看这个函数 谢谢
    法拉利 法拉利 法拉利
    2009年6月23日 2:46

答案

  • 在treble中result是一个临时变量,在该函数执行完毕后即释放.该函数执行完毕被释放了后你再输出访问的就可能是一个野指针,正常显示只是偶然而已.局部的临时变量是分配在程序的栈里的,如果这时没有其他函数的数据存入栈里覆盖的话,原来的变量值就不会被覆盖,你访问就可能成功,但是大多数情况下原变量所在的位置会被覆盖的.你知道他的原理就可以很容易写出一个测试程序.我就用int来说吧。
    #include <stdio.h>

    int* test()
    {
        int i = 1234;
        return &i;
    }

    void test2()
    {
     int c = 4321;
    }

    int main()
    {
     int *p = 0;
        p = test();
     test2();
     printf("%d", *p);
    }


    这个程序在Win32操作系统中运行的结果必然是4321(需要关闭C++的Max Speed优化,不然结果无法预料,在工程设置中的C/C++下的优化下的优化选项选为Disable),你不信?试试?神奇吧:)

    但是,这可不是编程什么技巧,实际使用中是非常危险的,因为栈的数据在C中并不是你能控制了的。


    0xBAADF00D
    2009年6月23日 4:20
    版主
  • 这个是由于当出了作用域后实际上这块内存已经是Release得了,只是没有清空而已。当需要进程再次需要内存的时候,可能会占用已被释放的内存。并将其值修改。此时如果再使用以前的指针使用这块内存就会是一个乱的值。
    这里你可以在treble的调用端。这样看一下
    double * result = treble(1.0);
    treble(2.0);

    当地一个treble返回的时候*result应该是3.0;
    而第二个treble返回的时候*result就变成了6.0;这显然是很危险的。

    麻烦把正确答案设为解答。
    2009年6月23日 4:24
    版主

全部回复

  • 拉利贵族正在努力学C++啊
    这里由于返回的内存已经被释放了,只是没有被重新赋值而已。
    在这个函数的调用端你这样试试
    double * result = treble(1.0);
    treble(2.0);
    再看看调用后result的值。
    同样问题在BSTR被free后尤为明显。


    麻烦把正确答案设为解答。
    2009年6月23日 3:17
    版主
  • 拉利贵族正在努力学C++啊
    这里由于返回的内存已经被释放了,只是没有被重新赋值而已。
    在这个函数的调用端你这样试试
    double * result = treble(1.0);
    treble(2.0);
    再看看调用后result的值。
    同样问题在BSTR被free后尤为明显。


    麻烦把正确答案设为解答。

    呵呵 是啊我正在努力学C++ 以后还请多多指教啊!!呵呵

    斑竹 既然已经被释放了 那么怎么还能获取到正确的值?书上的结果是显示错误的 因为这个函数我是用一个指针来保存这个函数的返回值 然后用*prt这样的指针在
    cout << *prt << endl;
    这样打印出来 书上打印的结果是一堆乱数字!!但是我的结果是正确的 我给函数传参传一个5.0进去 返回结果就是15了 这不是我想要的结果 我想要的是一个错误的结果
    但是它给我显示正确结果了!!

    这个函数本应该是错误的 必须修改成

    double* treble(double data)
    {
     double* result = new double(0.0);
     result = 3.0 * data;
     return result;
    }
    这样才能返回一个想要的15结果

    但是我没改成这样 就直接是
    double* treble(double data)
    {
     double result = 0.0;
     result = 3.0 * data;
     return &result;
    }
     也能是正确的 我很郁闷啊!!想它出错的时候它就是不出
    而且这个函数应该回返回错误的结果的啊? 因为函数结果 函数体内的double自动变量应该也是跟着被销毁了 这样就没有返回 而接收这个返回的指针就指向了另外一个占用了这块内存的数据的啊?  还是因为我的电脑内存里面很干净所以只有它一个数据所以打印它出来了?

    法拉利 法拉利 法拉利
    2009年6月23日 4:09
  • 在treble中result是一个临时变量,在该函数执行完毕后即释放.该函数执行完毕被释放了后你再输出访问的就可能是一个野指针,正常显示只是偶然而已.局部的临时变量是分配在程序的栈里的,如果这时没有其他函数的数据存入栈里覆盖的话,原来的变量值就不会被覆盖,你访问就可能成功,但是大多数情况下原变量所在的位置会被覆盖的.你知道他的原理就可以很容易写出一个测试程序.我就用int来说吧。
    #include <stdio.h>

    int* test()
    {
        int i = 1234;
        return &i;
    }

    void test2()
    {
     int c = 4321;
    }

    int main()
    {
     int *p = 0;
        p = test();
     test2();
     printf("%d", *p);
    }


    这个程序在Win32操作系统中运行的结果必然是4321(需要关闭C++的Max Speed优化,不然结果无法预料,在工程设置中的C/C++下的优化下的优化选项选为Disable),你不信?试试?神奇吧:)

    但是,这可不是编程什么技巧,实际使用中是非常危险的,因为栈的数据在C中并不是你能控制了的。


    0xBAADF00D
    2009年6月23日 4:20
    版主
  • 这个是由于当出了作用域后实际上这块内存已经是Release得了,只是没有清空而已。当需要进程再次需要内存的时候,可能会占用已被释放的内存。并将其值修改。此时如果再使用以前的指针使用这块内存就会是一个乱的值。
    这里你可以在treble的调用端。这样看一下
    double * result = treble(1.0);
    treble(2.0);

    当地一个treble返回的时候*result应该是3.0;
    而第二个treble返回的时候*result就变成了6.0;这显然是很危险的。

    麻烦把正确答案设为解答。
    2009年6月23日 4:24
    版主