鱼C论坛

 找回密码
 立即注册
查看: 1819|回复: 12

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

[复制链接]
发表于 2017-2-28 16:06:49 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

无法访问内存单元

无法访问内存单元
最佳答案
2017-3-2 00:28:47
看代码没有看出具体的错误,当你的结构体比较大可能在没被使用时,系统释放掉一些占用的内存 导致结构体头指向的位置变成野指针
尝试使用结构体指针用malloc分配内存 或者把结构体memset一下试试
内存问题很烦的 你试着吧结构体精简或者弄成多个结构体复合
对内存管理这块不是很清楚,问问工作中有经验的大牛吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-2-28 16:08:58 | 显示全部楼层
这个问题困扰自己好久了,什么原因啊啊啊啊啊啊啊啊
我是在Linux环境下,用GDB跟踪调试的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-2-28 17:24:34 | 显示全部楼层
本帖最后由 lumber2388779 于 2017-2-28 17:26 编辑

0 0你至少贴点代码什么的
这样我也不知道你问题出在哪
就你所说的,你的结构体是不是静态的,你创建结点的时候是否数据超过了结构体导致溢出
关注下你每个指针吧,确认不会变成野指针或者改变了指针指定的位置
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-2-28 22:49:13 | 显示全部楼层
没代码你要怎么说?

通常是越界问题或者指针丢失问题……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 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[VERTEX_MAX];                                                      
        double Edges[VERTEX_MAX][VERTEX_MAX];
        int isMainLink[VERTEX_MAX][VERTEX_MAX];
        int isTrav[VERTEX_MAX];                                                      
        int VertexNum;                                                               
        int EdgeNum;                                                                  
        int GraphType;                                                               
        int isTwoEdges[VERTEX_MAX][VERTEX_MAX];   
                                                                                     
}MatrixGraph;  

typedef struct Station{   
  char id[255];           
  char name[255];         
  char v[255];            
  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[hkv].oo_kv_bus_fa > 0))
                {
                        int _bptr = kv_mod[hkv].oo_kv_bus_fa;
                        do{
                                int _bus = oo_r_kv_bus_mod[_bptr].ichild;
                                //bus_mod.v_pre:母线电压量测值,v:电压估计值
                                if(bus_mod[_bus].v_pre >= st_v)
                                {
                                        st_v = bus_mod[_bus].v_pre;
                                }
                                _bptr=oo_r_kv_bus_mod[_bptr].bptr;
                        }while(_bptr > -1);
                }
                if(st_v < 1.0 )//还有最高电压等级没有母线建模的厂站,added by sxr
                {
                        st_v = bs_mod[kv_mod[hkv].ibs].v * kv_mod[hkv].nomvol;       
                }
                //山东线路两端的厂站
                if(st_mod[i].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[i].name);
                        if(ret > -1)
                        {
                                _st_x = st_xy[ret].st_x;
                                _st_y = st_xy[ret].st_y;
                        }
                        */
                       
                        char _id[255];
                        sprintf(_id,"%ld",st_mod[i].id);
                       
                        char _v[255];
                        sprintf(_v,"%.1f", st_v);
                        //============================================================================================                
                        stationList=insert_StationList(stationList,_id,st_mod[i].name,_v);
                        stationCount++;
                    //end
                    
                        printf("<station_data id=\"%d\" name=\"%s\" v=\"%.1f\"/>\n",
                                st_mod[i].id, st_mod[i].name, st_v);
                        st_mod[i].ibsl = 1;
                }
        }
       
           Station *LHead3=stationList;
           
       
        for(i=0;i<lv_ln_mod;i++)
        {
                int ist, zst;
                ist = kv_mod[ln_mod[i].ikv].ist;
                zst = kv_mod[ln_mod[i].zkv].ist;
                if(ist == zst) continue;
               
                int kv_type = find_kvvl(kv_mod[ln_mod[i].ikv].vl);
                int ln_class = 0;
                if(kv_mod[ln_mod[i].ikv].vl >= 500) {ln_class = 2;}
                else if(kv_mod[ln_mod[i].ikv].vl >= 200 && kv_mod[ln_mod[i].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[i].iisland0 == 1)
                {
                                               
                        char _id[255];
                        sprintf(_id,"%ld",ln_mod[i].id);
                       
                        char i_id[255];
                        sprintf(i_id,"%ld",st_mod[ist].id);
                       
                        char j_id[255];
                        sprintf(j_id,"%ld",st_mod[zst].id);
                        char vtype[255];
                        sprintf(vtype,"%d",kv_type);
                        char _class[255];
                        sprintf(_class,"%d",ln_class);
                       
                        char _pi[255];
                        sprintf(_pi,"%.1f",ln_mod[i].pi_pre);
                       
                        char _pz[255];
                        sprintf(_pz,"%.1f",ln_mod[i].pz_pre);
                       
                        char _x[255];
                        sprintf(_x,"%f",ln_mod[i].x);
                       
                        lineList=insert_LineList(lineList,_id,i_id,j_id,ln_mod[i].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{
                   int  stri_id=atoi(nP3->sti_id);
                                           int  strj_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[i],stri_id)==0 && strcmp(G.Vertex[j],strj_id)==0)                    
                                          if((G.Vertex[i]==stri_id)&&(G.Vertex[j]==strj_id))
                                              {
                                                    if(G.Edges[i][j]== MAXVALUE)
                                                    {
                                                        //G.Edges[i][j]=1;
                                                        //G.Edges[j][i]=1;
                                                       
                                                        delt_p = fabs(atof(nP3->pi)+atof(nP3->pz));
                                                        if(delt_p < 0.01)
                                                        {
                                                                G.Edges[j][i]=0.01;
                                                                G.Edges[i][j]=0.01;           
                                                        }
                                                        else
                                                        {
                                                                G.Edges[j][i]=delt_p;
                                                                G.Edges[i][j]=delt_p;
                                                        }                          
                                                    }                               
                                                       else
                                                     {
                                                             G.isTwoEdges[i][j]=1;
                                                             G.isTwoEdges[j][i]=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;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-1 10:40:18 | 显示全部楼层
lumber2388779 发表于 2017-2-28 17:24
0 0你至少贴点代码什么的
这样我也不知道你问题出在哪
就你所说的,你的结构体是不是静态的,你创建结点的 ...

源代码有点长,我整理了下放在了楼上;先问一句,有没有可能是变量G0这个地址保存的结构体太大了,使得CreatSpanningTree()函数调用的时候没有足够大的内存保存数据,如果是怎么处理,把*G0分两个结构体保存?
麻烦帮我瞅一眼,谢谢了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-1 10:43:46 | 显示全部楼层
zealstar 发表于 2017-2-28 22:49
没代码你要怎么说?

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

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

使用道具 举报

发表于 2017-3-1 11:48:42 | 显示全部楼层
最重要的CreatSpanningTree()函数反而没贴出来- -
个人建议结构体用指针去处理
你的CreatSpanningTree()是把整个树结构存到MatrixGraph结构中?还是把G当做根节点,感觉结构体是不是用错了?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-1 15:39:24 | 显示全部楼层
for(j=0;j<G->VertexNum;j++)                                                                                     
                {                                                                                                               
                        TreeG.Edges[j]=MAXVALUE;                                                                                   
                        TreeG.isMainLink[j]=0;                                                                                     
                        if(G->isMainLink[j]==1 && G->Edges[j] != MAXVALUE)                                                      
                        {                                                                                                             
                                  TreeG.Edges[j]=G->Edges[j];                                                                                                        
                                TreeG.isMainLink[j]=1;                                                                                          
                                                                                                                                            
                                    TreeG.Edges[j]=G->Edges[j];                                                                       
                                TreeG.isMainLink[j]=1;                                                                                                       
                        }                                                                                                             
                } 
这一段代码 Edges是二维数组 你弄成一维了 isMainLink也一样 你的i都没用到
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 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[i] =0;                                                                                                
        }                                                                                                                 
            //printf("生成树的节点和边:\n");                                                                             
            printf("按广度优先遍历节点顺序:\n");                                                                          
            for(i=0;i<G->VertexNum;i++)                                                                                   
               {                                                                                                           
                       if(!G->isTrav[i])                                                                                         
                  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[i] = G->Vertex[i];                                                                             
        }                                                                                                                 
        //初始化                                                                                                         
        for(i=0;i<G->VertexNum;i++)                                                                                       
        {                                                                                                                 
                for(j=0;j<G->VertexNum;j++)                                                                                    
                {                                                                                                               
                        TreeG.Edges[i][j]=MAXVALUE;                                                                                   
                        TreeG.isMainLink[i][j]=0;                                                                                    
                        if(G->isMainLink[i][j]==1 && G->Edges[i][j] != MAXVALUE)                                                      
                        {                                                                                                            
                                  TreeG.Edges[i][j]=G->Edges[i][j];                                                                                                       
                                TreeG.isMainLink[i][j]=1;                                                                                          
                                                                                                                                           
                                    TreeG.Edges[j][i]=G->Edges[j][i];                                                                       
                                TreeG.isMainLink[j][i]=1;                                                                                                      
                        }                                                                                                            
                }                                                                                                               
        }                                                                                                                 
        //printf("输出原始生成树:\n");                                                                                          
        printf("广度优先遍历邻接矩阵:\n");                                                                                
        Outlin(&TreeG);                                                                                                      
//输出邻接矩阵                                                                                                      
//===============================================================================================                  
                                                                                                                    
           //Outlin(G);                                                                                                   
            //寻找最小闭合环                                                                                               
        FindClosedLoop(G,&TreeG,m_LoopCircleStr);                                                                        
                                                                                                                                
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-3-1 16:50:37 | 显示全部楼层
lumber2388779 发表于 2017-3-1 15:39
这一段代码 Edges是二维数组 你弄成一维了 isMainLink也一样 你的i都没用到

网站自动把我代码中的【i】都删了。。。什么情况
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-3-2 00:28:47 | 显示全部楼层    本楼为最佳答案   
看代码没有看出具体的错误,当你的结构体比较大可能在没被使用时,系统释放掉一些占用的内存 导致结构体头指向的位置变成野指针
尝试使用结构体指针用malloc分配内存 或者把结构体memset一下试试
内存问题很烦的 你试着吧结构体精简或者弄成多个结构体复合
对内存管理这块不是很清楚,问问工作中有经验的大牛吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

太牛逼了,按你说的我把结构体用动态内存分配了一下,就不再出现段错误了。
那这么说,是不是因为我之前MatrixGraph G;分配内存空间时,由于可分配的整块的内存空间不够大,当需要用G保存的数据量超出时,就占用了其他地址,使得指针冲突,在函数调用的时候无法全部调用结构体G包含的全部地址,产生段错误,这么理解对吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-27 21:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表