之前做ACM题目时偶尔会出现段错误。段错误,之前也讲过,主要是内存的越界访问;但今天遇到的段错误的原因有些特殊,就是C++中的string类型也会引起段错误!!
先看源代码:
#include <iostream>
#include <string>
#include <cstdio>
#include <memory.h>
using namespace std;
struct Heap
{
string msg;
//char msg[10]; 这里是根源!!!
int param,prio;
} heap[60010];
//下滑操作
void siftDown(int start,int end)
{
//将start号结点向下调整直到end
int i=start,j=2*i;
heap[0]=heap[i]; //用heap[0]来临时保存i结点的值
while(j<=end)
{
//有右孩子并且右孩子比左孩子小时,或者当优先级相同并且j号结点后出现时将j保存右孩子
if(j<end&&heap[j].prio>heap[j+1].prio) ++j;
//比j号结点小时,不需调整
if(heap[0].prio<=heap[j].prio) //使其满足优先级相同时先到的先服务
break;
else
{
//向下调整
heap[i]=heap[j];
i=j;
j=2*j;
}
}
heap[i]=heap[0];
}
//向上调整的函数
//将结点start调整到根结点1为止
void siftUp(int start)
{
int j=start,i=j/2;
heap[0]=heap[j];
while(j>0)
{
if(heap[i].prio<=heap[0].prio)
break;
else
{
//向上调整工作
heap[j]=heap[i];
j=i;
i=i/2;
}
}
heap[j]=heap[0];
}
//插入操作的实现
bool insert(int& num,Heap& temp)
{
if(60000==num) return false;
++num;
heap[num]=temp;
siftUp(num);
return true;
}
//删除操作
bool removeMin(int& num,Heap& temp)
{
if(0==num)
return false;
//将根的信息通过参数返回
temp=heap[1];
heap[1]=heap[num]; //填补树根
--num;
siftDown(1,num); //将根结点下滑到尾部
return true;
}
int main()
{
char requ[4];
int num=0;
int para=0,pri=0; //para表示消息的参数,pri表示优先级
memset(heap,0,sizeof(heap));
while(cin>>requ)
{
Heap hTemp;
if(!strcmp(requ,"GET"))
{
if(!removeMin(num,hTemp))
printf("EMPTY QUEUE!\n");
else
cout<<hTemp.msg<<" "<<hTemp.param<<endl;
}
else
{
cin>>hTemp.msg>>hTemp.param>>hTemp.prio;
insert(num,hTemp);
}
}
}
重点是在结构体Heap中,当我将Heap中的成员msg由字符数组类型改为string类型时就会出现段错误,改回来时就AC。 这可能是由于编译器对C++所支持的标准不一样造成的,有些编译器可能对string类型支持的不是很好(包括之前用C++的类来做ACM题时也有段错误);而编译器对C语言支持的标准基本一致,所以做ACM题目时应尽量用C的语法或标准来做题,避免因编译器的不同导致一些看起来无法理解的错误。