浪里个狼 发表于 2017-2-28 16:06:49

函数调用时变量的内存地址变了,造成无法访问内存单元

如题如图,当我调用CreatSpanningTree()函数时,提示无法访问所示内存地址,而且这个地址和我调用函数前的G0地址不一样啊,为什么会出现这种内存地址变了的情况啊,求助各位大神给分析分析!!!
另外,G0保存的是一个大结构体,我发现当G0中的数据量不是很大的时候,调用函数可以成功;当G0中保存的数据过多时,发生了上述地址改变无法访问的情况,不明所以。。。。

浪里个狼 发表于 2017-2-28 16:08:58

这个问题困扰自己好久了,什么原因啊啊啊啊啊啊啊啊{:10_247:}{:10_247:}{:10_247:}
我是在Linux环境下,用GDB跟踪调试的

lumber2388779 发表于 2017-2-28 17:24:34

本帖最后由 lumber2388779 于 2017-2-28 17:26 编辑

0 0你至少贴点代码什么的
这样我也不知道你问题出在哪
就你所说的,你的结构体是不是静态的,你创建结点的时候是否数据超过了结构体导致溢出
关注下你每个指针吧,确认不会变成野指针或者改变了指针指定的位置

zealstar 发表于 2017-2-28 22:49:13

没代码你要怎么说?

通常是越界问题或者指针丢失问题……{:10_258:}

浪里个狼 发表于 2017-3-1 10:39:07

#define MAXV 500                                             
#define VERTEX_MAX 800                                                         
#define MAXVALUE 32767                                                         
#define MAX_VERTAX_NUM 500                                                      
#define QUEUE_MAXSIZE 600                                                      
#define charLen 20                                                            

typedef struct                                                                  
{
        int Vertex;                                                      
        double Edges;
        int isMainLink;
        int isTrav;                                                      
        int VertexNum;                                                               
        int EdgeNum;                                                                  
        int GraphType;                                                               
        int isTwoEdges;   
                                                                                     
}MatrixGraph;

typedef struct Station{   
char id;         
char name;         
char v;            
struct Station *next;   
}Station;               

int rx_check(char *dv_name)
{                           
    int        ret, i, j;
    MatrixGraph G;
    struct Station *nSP,*Sp1,*SHead;
    nSP = (struct Station*)malloc(sizeof(struct Station));
    stationList=nSP;
    SHead=nSP;
    Sp1=nSP;
   
    setstationCount() ;
   
    struct Line *nLP,*Lp1,*Lhead;
    nLP = (struct Line*)malloc(sizeof(struct Line));
    lineList=nLP;
    Lhead=nLP;
    Lp1=nLP;
   
    setLineCount();

        for(i=0;i<lv_st_mod;i++)
        {
                float kvvl = 0.0;                                                                                                                                        //最高电压等级
                int   hkv = -1;                                                                                               
                if(hkv <0) continue;
                float st_v = 0.0;
                //找最大电压等级的母线
                if((hkv > -1)&&(kv_mod.oo_kv_bus_fa > 0))
                {
                        int _bptr = kv_mod.oo_kv_bus_fa;
                        do{
                                int _bus = oo_r_kv_bus_mod.ichild;
                                //bus_mod.v_pre:母线电压量测值,v:电压估计值
                                if(bus_mod.v_pre >= st_v)
                                {
                                        st_v = bus_mod.v_pre;
                                }
                                _bptr=oo_r_kv_bus_mod.bptr;
                        }while(_bptr > -1);
                }
                if(st_v < 1.0 )//还有最高电压等级没有母线建模的厂站,added by sxr
                {
                        st_v = bs_mod.ibs].v * kv_mod.nomvol;       
                }
                //山东线路两端的厂站
                if(st_mod.ibsl == 2)                                                                                                //不等于2就不定级了?
                {
                        int st_class = 0;
                        if(kvvl >= 500) {st_class = 2;}
                        else if((kvvl < 500)&&(kvvl > 200))
                        {
                                st_class = 3;
                        }
                        else
                        {
                                continue;       
                        }
                       
                        int _st_x=-1;
                        int _st_y=-1;
                        /*
                        ret = find_st_xy(st_mod.name);
                        if(ret > -1)
                        {
                                _st_x = st_xy.st_x;
                                _st_y = st_xy.st_y;
                        }
                        */
                       
                        char _id;
                        sprintf(_id,"%ld",st_mod.id);
                       
                        char _v;
                        sprintf(_v,"%.1f", st_v);
                        //============================================================================================              
                        stationList=insert_StationList(stationList,_id,st_mod.name,_v);
                        stationCount++;
                  //end
                  
                        printf("<station_data id=\"%d\" name=\"%s\" v=\"%.1f\"/>\n",
                                st_mod.id, st_mod.name, st_v);
                        st_mod.ibsl = 1;
                }
        }
       
           Station *LHead3=stationList;
           
       
        for(i=0;i<lv_ln_mod;i++)
        {
                int ist, zst;
                ist = kv_mod.ikv].ist;
                zst = kv_mod.zkv].ist;
                if(ist == zst) continue;
               
                int kv_type = find_kvvl(kv_mod.ikv].vl);
                int ln_class = 0;
                if(kv_mod.ikv].vl >= 500) {ln_class = 2;}
                else if(kv_mod.ikv].vl >= 200 && kv_mod.ikv].vl < 300) {ln_class = 3;}
                else {continue;}
               
                int _st_xi=-1;
                int _st_yi=-1;
                int _st_xj=-1;
                int _st_yj=-1;
                if(ln_mod.iisland0 == 1)
                {
                                               
                        char _id;
                        sprintf(_id,"%ld",ln_mod.id);
                       
                        char i_id;
                        sprintf(i_id,"%ld",st_mod.id);
                       
                        char j_id;
                        sprintf(j_id,"%ld",st_mod.id);
                        char vtype;
                        sprintf(vtype,"%d",kv_type);
                        char _class;
                        sprintf(_class,"%d",ln_class);
                       
                        char _pi;
                        sprintf(_pi,"%.1f",ln_mod.pi_pre);
                       
                        char _pz;
                        sprintf(_pz,"%.1f",ln_mod.pz_pre);
                       
                        char _x;
                        sprintf(_x,"%f",ln_mod.x);
                       
                        lineList=insert_LineList(lineList,_id,i_id,j_id,ln_mod.name,vtype,_class,_pi,_pz,_x);       
                        LineCount++;                       
                       
                }
        }

        //GJ---------构造邻接矩阵-----------//
           int staCount=getstationCount();
           G.VertexNum=staCount;
           G.EdgeNum =getLineCount();

   
   //边赋值
       Line *nP3 =lineList;
       int linecount,dLineCount;
       double delt_p = 0.0f;
       do{
                 intstri_id=atoi(nP3->sti_id);
                                           intstrj_id=atoi(nP3->stj_id);
                                           char* pi=nP3->pi;
                  if(strcmp(pi,"0.0") )
                  {
                         for(i=0;i<staCount;i++)
                         {       
                                  for(j=0;j<staCount;j++)
                               {
                                    //if(strcmp(G.Vertex,stri_id)==0 && strcmp(G.Vertex,strj_id)==0)                  
                                      if((G.Vertex==stri_id)&&(G.Vertex==strj_id))
                                            {
                                                  if(G.Edges== MAXVALUE)
                                                  {
                                                        //G.Edges=1;
                                                        //G.Edges=1;
                                                       
                                                        delt_p = fabs(atof(nP3->pi)+atof(nP3->pz));
                                                        if(delt_p < 0.01)
                                                        {
                                                                G.Edges=0.01;
                                                                G.Edges=0.01;           
                                                        }
                                                        else
                                                        {
                                                                G.Edges=delt_p;
                                                                G.Edges=delt_p;
                                                        }                          
                                                  }                             
                                                     else
                                                   {
                                                           G.isTwoEdges=1;
                                                           G.isTwoEdges=1;
                                                           dLineCount++;                              
                                             }                         
                                                linecount++;//linecount?
                                                                        }
                               }
                          }                          
                }
               nP3=nP3->next;
       }while(nP3!=Lhead );                                        //因为边的信息是反着排的
   
   printf("LineCount is %d, dLineCount is %d. \n",linecount,dLineCount);       

   dyn_string_t m_LoopCircleStr=dyn_string_new(0);
   CreateSpanningTree(&G,m_LoopCircleStr);
   printf("环有:%s\n",m_LoopCircleStr->s);

   //以先路id形式表示各个环路
   //===============================================================================================后面还有很多行,省略了……
      
   
   //end---------------//
        free(nSP);
        free(nLP);
        free(loopHead);
        free(loopTail);
       
        nSP = NULL;
        nLP = NULL;
        loopHead = NULL;
        loopTail = NULL;
       
        return 1;
}

浪里个狼 发表于 2017-3-1 10:40:18

lumber2388779 发表于 2017-2-28 17:24
0 0你至少贴点代码什么的
这样我也不知道你问题出在哪
就你所说的,你的结构体是不是静态的,你创建结点的 ...

源代码有点长,我整理了下放在了楼上;先问一句,有没有可能是变量G0这个地址保存的结构体太大了,使得CreatSpanningTree()函数调用的时候没有足够大的内存保存数据,如果是怎么处理,把*G0分两个结构体保存?
麻烦帮我瞅一眼,谢谢了

浪里个狼 发表于 2017-3-1 10:43:46

zealstar 发表于 2017-2-28 22:49
没代码你要怎么说?

通常是越界问题或者指针丢失问题……

兄弟,源代码放楼上了。现在,我知道程序是在调用CreatSpanningTree()函数的时候出现的段错误,在调用函数的前一条语句时,变量的地址还都对,结构体中数据也可以正常查看,但是单步运行到CreatSpanningTree()函数时,发生了变量的指针错误,有可能时因为调用的变量数据量太大(占用了过多内存)导致指针丢失的吗?

lumber2388779 发表于 2017-3-1 11:48:42

最重要的CreatSpanningTree()函数反而没贴出来- -
个人建议结构体用指针去处理
你的CreatSpanningTree()是把整个树结构存到MatrixGraph结构中?还是把G当做根节点,感觉结构体是不是用错了?

lumber2388779 发表于 2017-3-1 15:39:24

for(j=0;j<G->VertexNum;j++)                                                                                    
                {                                                                                                               
                        TreeG.Edges=MAXVALUE;                                                                                 
                        TreeG.isMainLink=0;                                                                                    
                        if(G->isMainLink==1 && G->Edges != MAXVALUE)                                                      
                        {                                                                                                            
                                  TreeG.Edges=G->Edges;                                                                                                      
                              TreeG.isMainLink=1;                                                                                          
                                                                                                                                          
                                    TreeG.Edges=G->Edges;                                                                     
                              TreeG.isMainLink=1;                                                                                                      
                        }                                                                                                            
                }
这一段代码 Edges是二维数组 你弄成一维了 isMainLink也一样 你的i都没用到

浪里个狼 发表于 2017-3-1 16:49:59

是不是我粘贴的格式不对啊,网站自动把我代码中的【i】都删了。。。

//生成树                                                                                                            
void CreateSpanningTree(MatrixGraph *G,dyn_string_t m_LoopCircleStr)                                                
{                                                                                                                  
        int i,j;                                                                                                         
        for(i=0;i<G->VertexNum;i++)                                                                                       
        {                                                                                                               
                G->isTrav =0;                                                                                                
        }                                                                                                               
            //printf("生成树的节点和边:\n");                                                                           
            printf("按广度优先遍历节点顺序:\n");                                                                        
            for(i=0;i<G->VertexNum;i++)                                                                                 
               {                                                                                                         
                       if(!G->isTrav)                                                                                       
                  CBFSM(G,i);                                                                                             
      }                                                                                                         
            printf("\n");                                                                                                
                                                                                                                  
            //构造生成树图                                                                                                
            MatrixGraph TreeG;                                                                                          
            TreeG.VertexNum = G->VertexNum;                                                                              
        TreeG.EdgeNum=G->EdgeNum;                                                                                       
        //printf("构造生成树\n");                                                                                       
        //顶点赋值                                                                                                      
        for(i=0;i<G->VertexNum;i++)                                                                                       
            {                                                                                                            
                    TreeG.Vertex = G->Vertex;                                                                           
        }                                                                                                               
        //初始化                                                                                                         
        for(i=0;i<G->VertexNum;i++)                                                                                       
        {                                                                                                               
                for(j=0;j<G->VertexNum;j++)                                                                                    
                {                                                                                                               
                        TreeG.Edges=MAXVALUE;                                                                                 
                        TreeG.isMainLink=0;                                                                                    
                        if(G->isMainLink==1 && G->Edges != MAXVALUE)                                                      
                        {                                                                                                            
                                  TreeG.Edges=G->Edges;                                                                                                       
                                TreeG.isMainLink=1;                                                                                        
                                                                                                                                           
                                  TreeG.Edges=G->Edges;                                                                     
                                TreeG.isMainLink=1;                                                                                                    
                        }                                                                                                            
                }                                                                                                               
        }                                                                                                               
        //printf("输出原始生成树:\n");                                                                                        
        printf("广度优先遍历邻接矩阵:\n");                                                                              
      Outlin(&TreeG);                                                                                                    
//输出邻接矩阵                                                                                                      
//===============================================================================================                  
                                                                                                                  
           //Outlin(G);                                                                                                   
          //寻找最小闭合环                                                                                             
        FindClosedLoop(G,&TreeG,m_LoopCircleStr);                                                                        
                                                                                                                              
}

浪里个狼 发表于 2017-3-1 16:50:37

lumber2388779 发表于 2017-3-1 15:39
这一段代码 Edges是二维数组 你弄成一维了 isMainLink也一样 你的i都没用到

网站自动把我代码中的【i】都删了。。。什么情况

lumber2388779 发表于 2017-3-2 00:28:47

看代码没有看出具体的错误,当你的结构体比较大可能在没被使用时,系统释放掉一些占用的内存 导致结构体头指向的位置变成野指针
尝试使用结构体指针用malloc分配内存 或者把结构体memset一下试试
内存问题很烦的 你试着吧结构体精简或者弄成多个结构体复合
对内存管理这块不是很清楚,问问工作中有经验的大牛吧

浪里个狼 发表于 2017-3-2 09:51:22

lumber2388779 发表于 2017-3-2 00:28
看代码没有看出具体的错误,当你的结构体比较大可能在没被使用时,系统释放掉一些占用的内存 导致结构体头指 ...

太牛逼了,按你说的我把结构体用动态内存分配了一下,就不再出现段错误了。
那这么说,是不是因为我之前MatrixGraph G;分配内存空间时,由于可分配的整块的内存空间不够大,当需要用G保存的数据量超出时,就占用了其他地址,使得指针冲突,在函数调用的时候无法全部调用结构体G包含的全部地址,产生段错误,这么理解对吧
页: [1]
查看完整版本: 函数调用时变量的内存地址变了,造成无法访问内存单元