none
cout后变量内容发生变化? RRS feed

  • 问题

  • 最近在VC6.0环境中做书后面的一些习题,发现这个问题。

    代码如下(已做了省略,无关的代码被我剔除)

    #include <iostream.h>

    struct Student
    {
     long number;
     Student * next;
    };

    Student * Create()
    {
     Student * pS;
     Student * pEnd;
     pS=new Student;
     cout<<"number?"<<endl;
     cin>>pS->number;
     Student * head=NULL;
     pEnd=pS;

     while (pS->number!=0)
     {
      if(head==NULL)
       head=pS;
      else
       pEnd->next=pS;

      pEnd=pS;
      pS=new Student;
      cout<<"number?"<<endl;
      cin>>pS->number;
     }
     pEnd->next=NULL;
     delete pS;
     return (head);
    }

    Student * Insert(Student * head,Student * stud)
    {
     if(head==NULL)
     {
      head=stud;
      stud->next=NULL;
      return head;
     }
     return head;
    }

    Student * SortList(Student * head)
    {
     Student * shead=NULL;
     Student * p=head;
     Student ps;

     while(p)
     {
      ps.number=p->number;
      p=p->next;
      shead=Insert(shead,&ps);
     }
     return shead;
    }

    void main()
    {
     Student * head;
     head=Create();

     head=SortList(head);
     cout<<head->number<<endl;
     cout<<head->number<<endl;

    }

    在VC6.0编译通过后,执行:只输入一个节点,number=1,然后以输入0的方式推出,打印head的内容,

    第一次打印的结果是1,正确,

    第二次打印的结果是个很大的负值,错误。

    两次打印中无任何语句。

    我想了半天没搞明白cout后变量里的内容怎么发生变化?

     

    2010年8月26日 3:22

答案

全部回复

  • 因为SortList中的ps是声明在栈中的,会在退出SortList的时候被释放掉,但是你把它的地址Insert到链表中,这样就产生了一些诡异的问题。尽管ps被释放掉之后,它的内容依然可以被访问,但并不确定它的内容什么时候会被改写,因为这段内存空间已经可以被系统使用了,系统什么时候用到它是不可知的。猜测在第一次cout的时候,cout需要多用一些空间,于是就占用了本来ps所用的空间,于是第二次cout出来的值就不对了。

    改的方法是把SortList中的ps也声明成指针。


    Shuhai Shen - I love programming, travel and photographing. Welcome to my blog: http://leonax.net
    2010年8月26日 4:44
  • 因为SortList中的ps是声明在栈中的,会在退出SortList的时候被释放掉,但是你把它的地址Insert到链表中,这样就产生了一些诡异的问题。尽管ps被释放掉之后,它的内容依然可以被访问,但并不确定它的内容什么时候会被改写,因为这段内存空间已经可以被系统使用了,系统什么时候用到它是不可知的。猜测在第一次cout的时候,cout需要多用一些空间,于是就占用了本来ps所用的空间,于是第二次cout出来的值就不对了。

    改的方法是把SortList中的ps也声明成指针。


    Shuhai Shen - I love programming, travel and photographing. Welcome to my blog:

    http://www.jf500.com

     


    2010年8月26日 5:08
  • 非常感谢。

    Student * SortList(Student * head)
    {
     Student * shead=NULL;
     Student * p=head;
     Student * ps=NULL;

     while(p)
     {
      ps=p;
      p=p->next;
      shead=Insert(shead,ps);
     }
     return shead;
    }

    把SortList改成这样,调试就通过了。

    不过我还是想请教一下:是否因为这里将ps声明为指针,而该指针指向的位置又不位于SortList所在栈区,所以退出后,变量就仍然能访问到?

    2010年8月26日 5:31
  • 嗯,对。new生成的对象都存放在堆中,不受函数作用域的影响。
    Shuhai Shen - I love programming, travel and photographing. Welcome to my blog: http://leonax.net
    2010年8月26日 5:36