#include<iostream>
#include<cstring>
using namespace std;
#define MAX 100
#define inf 10000
int A[MAX][MAX],visited[MAX],g[MAX];
typedef int elem_t;
typedef struct HeapStruct *Minheap;
struct HeapStruct{
elem_t H[MAX];//存储堆元素的数组
elem_t ph[MAX];
int size;//堆当前的元素个数
};void Bubbleup(HeapStruct Heap,int n)
{
while(n>1)
{
if(Heap.H[n]<Heap.H [n/2])
{
int tmp=Heap.H [n];
    Heap.H[n]=Heap.H[n/2];
    Heap.H[n/2]=tmp;
n=n/2;
}
else
break;
}}int ExtractMin(HeapStruct Heap)
{
int M=Heap.H[1];
int pa,child,temp1;
temp1=Heap.H[Heap.size];
Heap.size--;
//Heap.H[Heap.size]=0;
for(pa=1;pa*2 <=Heap.size ;pa=child)//向下冒泡
{
child=2*pa;
if(Heap.H[child] > Heap.H[child+1]&&Heap.size>=child+1)
child++;
if(temp1 > Heap.H[child])
Heap.H[pa] = Heap.H[child];
else
break;
}
Heap.H[pa]=temp1;
visited[g[M]]=1;//这里出的问题
return M;
}
void Heapinsert(HeapStruct Heap,int n)
{
Heap.H[++Heap.size]= n;
Bubbleup(Heap,Heap.size);
}
void prim(int m,int n,int A[MAX][MAX],int p[],HeapStruct Heap)
{
p[m]=0;
int temp=m;
visited[m]=1;
for(int k=1;k<=n;k++)//生成堆
{
if(A[m][k]!=0)
{
p[k]=m;
g[A[m][k]]=k;
Heapinsert(Heap,A[m][k]);
Heap.ph[k]=Heap.size;
}
}
m=g[ExtractMin(Heap)];
while(Heap.size!=0)
{
visited[m]=1;
for(int i=1;i<=n;i++)
{
if(A[m][i]<Heap.H[Heap.ph[i]]&&A[m][i]!=0&&visited[i]!=1)
{
p[i]=m;
g[A[m][i]]=i;
Heap.H[Heap.ph[i]]=A[m][i];
Bubbleup(Heap,Heap.ph[i]);
}
}
m=g[ExtractMin(Heap)];

}
for(int j=1;j<=n;j++)
if(j!=temp)
cout<<p[j]<<"->"<<j<<endl;}
First-chance exception in project2.exe: 0xC0000005: Access Violation.

解决方案 »

  1.   

    崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止
    判断是否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。如果该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
    #include <time.h>
    #include <stdlib.h>
    #include <windows.h>
    int main() {
        int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11]    srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。
        while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。
            b[(a=rand()%11)]=0;
            Sleep(100);
            b[(a=rand()%11)]=1;
            Sleep(100);
            b[(a=rand()%11)]=2;
            Sleep(100);
            b[(a=rand()%11)]=3;
            Sleep(100);
            b[(a=rand()%11)]=4;
            Sleep(100);
        }
        return 0;
    }
      

  2.   

    当你运行程式得到了一个AV(Access Violation)错误的时候,这意味着你的程式正在试图访问一块不再有效的内存,请注意我所提到的“不再 ”有效。大多数的情况下,出现这个错误要么是因为你试图访问一块已经被释放的内存,要么是想使用一个还未创建对象的指针。访问数组visited越位了吧给的代码连main函数也没有,没注释,怎么调用也不知道,什么也没有,怎么看
      

  3.   

    visited对应数组,取下标等,有问题。越界了
      

  4.   

    int main()
    {
    memset(g,0,sizeof(g));
    memset(visited,0,sizeof(visited));//初始化为0
    int n,m,p[MAX];
    HeapStruct Heap;
    Heap.size=0;
    cout<<"请输入顶点个数:";
    cin>>n;
    for(int i=1;i<=n;i++)
    {
    Heap.H[i]=inf;
    cout<<"请输入与"<<i<<"相邻接的顶点的权重: ";
    for(int j=1;j<=n;j++)
    cin>>A[i][j];
    }
    cout<<"请输入你想创建的最小生成树的起点:";
    cin>>m;
    prim(m,n,A,p,Heap);
    return 0;
    }
    抱歉,这是主函数
      

  5.   

    抱歉哈,忘贴主函数了,还有那个visited怎么越位了
      

  6.   

    我的visited大小是100啊,g(m)是6,应该不会越界