Chinaunix

标题: 在Ubuntu下运行会段错误,Win下可以正常运行,为什么? [打印本页]

作者: janusle    时间: 2006-12-22 23:41
标题: 在Ubuntu下运行会段错误,Win下可以正常运行,为什么?
以下是我数据结构课程中的一个作业.我在Ubuntu下用g++编译后,运行会显示"段错误",但是在Win下用g++编译后,运行没有提示.我不知道我哪里出问题了.用gdb调试,程序似乎是在其中的一个FilterDown函数中中断的.但是我看不出问题.诸位帮忙看看.


  1. #include<iostream>
  2. using namespace std;


  3. class heap{
  4. public:
  5.   heap(int size = 10):maxsize(size) , currentsize(0) { heapArray = new int[10]; }
  6.   heap(int a[] , int size);  //通过一个数组构建一个堆.
  7.   ~heap(){delete [] heapArray;}
  8.   int getTop(){return heapArray[0];}
  9.   bool deletetop();  //删除堆顶
  10.   bool insert(int data); //插入一个元素
  11.   bool isempty() const{ return currentsize == 0; }
  12.   bool isfull() const{ return currentsize == maxsize; }
  13.   int sizeofheap() { return currentsize; }
  14.   void setempty(){ currentsize = 0 ;}
  15.   

  16. private:
  17.   int *heapArray;
  18.   int currentsize;
  19.   int maxsize;
  20.   void FilterDown(int p); //向下调整函数
  21.   void FilterUp(int p );  //想上调整函数



  22. };

  23. bool heap::deletetop()
  24. {
  25. if ( currentsize == 0 )
  26.   return false;         
  27. heapArray[0] = heapArray[currentsize-1];
  28. currentsize--;
  29. FilterDown(0);
  30. return true;

  31. }

  32. bool heap::insert(int data)
  33. {
  34. if ( currentsize == maxsize )
  35.   return false;

  36. heapArray[currentsize] = data;
  37. FilterUp(currentsize);
  38. currentsize++;
  39. return true;
  40. }

  41. void heap::FilterUp(int p)
  42. {
  43. int temp;
  44. int i = p;
  45. int j = (i - 1) / 2;
  46. while( j >= 0 )
  47.   {
  48.     if ( heapArray[i] < heapArray[j] )
  49.      {
  50.        temp = heapArray[i];
  51.        heapArray[i] = heapArray[j];
  52.        heapArray[j] = temp;
  53.      }
  54.     else
  55.      break;

  56.     i = j;
  57.     j = (j - 1) / 2;
  58.   }
  59. }

  60. heap::heap(int a[] , int size)
  61. {
  62.   maxsize = size + 10;
  63.   heapArray = new int[maxsize];
  64.   heapArray = a;
  65.   currentsize = size;
  66.   int i = (currentsize - 2) / 2;
  67.   while(i >= 0)
  68.    {
  69.      FilterDown(i--);
  70.    }
  71. }



  72. void heap::FilterDown(int p)
  73. {
  74.   int i = p;
  75.   int j = i * 2 + 1;
  76.   int temp;
  77.   while ( j < currentsize )
  78.    {
  79.       
  80.      if ( ( (j + 1) < currentsize ) && ( heapArray[j] > heapArray[j+1] ) )
  81.        j++;
  82.    
  83.      if ( heapArray[i] > heapArray[j] )
  84.       {
  85.         temp = heapArray[i];
  86.         heapArray[i] = heapArray[j];
  87.         heapArray[j] = temp;
  88.       }  
  89.      else
  90.       break;

  91.      i = j;
  92.      j = j * 2 + 1;

  93.    }     



  94. }

  95. int main()
  96. {
  97.   int a[] = {80 , 57 , 99 , 35 , 23 , 11 , 74 , 29 , 62 , 16};
  98.   heap b(a , 10);
  99.   b.insert(14);
  100.   b.deletetop();

  101. }
复制代码

作者: cjaizss    时间: 2006-12-22 23:47
自己学着拿gdb调
作者: cjaizss    时间: 2006-12-23 01:31
不过最后好心的我还是帮你看了一下。
错误居然发生在bool heap::insert(int data)里的
heapArray[currentsize] = data;
watch heapArray,发现,居然是这句修改了heapArray的值
很绯疑所思是吗?
哦,原来heapArray本来指着main里的a数组,a的长度是10;
currentsize 也是10,哦,越界。
而且正好heapArray[current]存的就是heapArray这个变量。
教训啊,这个故事告诉我们越界访问的后果是多么的严重
作者: janusle    时间: 2006-12-23 13:09
谢谢,谢谢。我不应该直接指向那个数组,应该复制一下。呵呵

指针看来是很危险的东西!

[ 本帖最后由 janusle 于 2006-12-23 14:12 编辑 ]
作者: ssffzz1    时间: 2006-12-23 13:47
Windows的检测机制没有linux的严格.
作者: galaxywar    时间: 2006-12-23 18:30
原帖由 ssffzz1 于 2006-12-23 13:47 发表
Windows的检测机制没有linux的严格.

不是这个原因. 越界访问未必一定会core dump, 如果你访问的地址对当前进程是有效而且可读的就不会有事(对于读来说), 具有一定偶然性. 这个版里以前有篇贴子是关于malloc实现,还有sbrk()和brk()的讨论, 可以看一下.

据我碰到过的一些跨平台的程序, 明明有越界访问,  在Unix下就是比在Windows下容易重现的多. 我估计是windows下内存分配机制有所不同,到底有什么不同, 我也不清楚.




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2