【问题标题】:Segementation fault if accessing struct member in library function访问库函数中的结构成员时出现分段错误
【发布时间】:2020-05-14 02:23:24
【问题描述】:

以下问题: 在我的主程序中,我声明 struct 变量,然后将地址传递给库函数(共享对象,由我编译)。库函数应该初始化结构,但它会因分段错误而崩溃。当结构的成员(类型 int)设置为 0 时会发生崩溃。如果我在主程序中设置相同的成员,则不会发生此问题。

主程序:C++(用g++编译)

rnxctr_t tRNX;
tRNX.ephsat = 0;  // <-- works
init_rnxctr(&tRNX);

库函数:C(用 gcc 编译)

extern int init_rnxctr(rnxctr_t *rnx)
{
    gtime_t time0={0};
    obsd_t data0={{0}};
    eph_t  eph0={0,-1,-1};
    geph_t geph0={0,-1};
    seph_t seph0={0};
    int i,j;

    trace(3,"init_rnxctr:\n");

    rnx->obs.data=NULL;
    rnx->nav.eph =NULL;
    rnx->nav.geph=NULL;
    rnx->nav.seph=NULL;

    if (!(rnx->obs.data=(obsd_t *)malloc(sizeof(obsd_t)*MAXOBS ))||
        !(rnx->nav.eph =(eph_t  *)malloc(sizeof(eph_t )*MAXSAT ))||
        !(rnx->nav.geph=(geph_t *)malloc(sizeof(geph_t)*NSATGLO))||
        !(rnx->nav.seph=(seph_t *)malloc(sizeof(seph_t)*NSATSBS))) {
        free_rnxctr(rnx);
        return 0;
    }
    rnx->time=time0;
    rnx->ver=0.0;
    rnx->sys=rnx->tsys=0;
    for (i=0;i<6;i++) for (j=0;j<MAXOBSTYPE;j++) rnx->tobs[i][j][0]='\0';
    rnx->obs.n=0;
    rnx->nav.n=MAXSAT;
    rnx->nav.ng=NSATGLO;
    rnx->nav.ns=NSATSBS;
    for (i=0;i<MAXOBS ;i++) rnx->obs.data[i]=data0;
    for (i=0;i<MAXSAT ;i++) rnx->nav.eph [i]=eph0;
    for (i=0;i<NSATGLO;i++) rnx->nav.geph[i]=geph0;
    for (i=0;i<NSATSBS;i++) rnx->nav.seph[i]=seph0;
    rnx->ephsat=0;    // <-- segmentation fault
    rnx->opt[0]='\0';

    return 1;
}

结构定义:

typedef struct {        /* rinex control struct type */
    gtime_t time;       /* message time */
    double ver;         /* rinex version */
    char   type;        /* rinex file type ('O','N',...) */
    int    sys;         /* navigation system */
    int    tsys;        /* time system */
    char   tobs[7][MAXOBSTYPE][4]; /* rinex obs types */
    obs_t  obs;         /* observation data */
    nav_t  nav;         /* navigation data */
    sta_t  sta;         /* station info */
    int    ephsat;      /* ephemeris satellite number */
    char   opt[256];    /* rinex dependent options */
} rnxctr_t;

更新:完整头文件的链接:rtklib.h

一些观察

仅当我启用(定义)库的一些可选功能(DENAGAL、DENACMP)时才会出现此问题。但是与“正常”版本的差异根本无法解释问题。发布的代码中唯一改变的是MAXSAT 定义。

更新: 我刚刚意识到,MAXSAT 的更改确实会改变rnxctr_t 内部结构的大小(例如nav_t

用gdb我可以看到主程序和函数中有些成员的地址是不同的。 主要:

  • &tRNX: 0x7ffffffc6e10
  • &tRNX.nav: 0x7ffffffc7548
  • &tRNX.ephsat: 0x7fffffffd290

功能:

  • rnx: 0x7ffffffc6e10
  • &rnx->导航:0x7ffffffc7548
  • &rnx->ephsat: 0x800000026ef8

最后一点真的让我很困惑,因为我不明白这是怎么发生的。

最好的问候 迈克尔

【问题讨论】:

  • 这是 C 还是 C++?
  • 请贴出gtime_tobs_tnav_tsta_t的定义。请张贴MAXOBSTYPEMAXOBSMAXSAT NSATGLONSATSBS的定义。我认为for (i=0;i&lt;6;i++) 应该算到7
  • 选项集是否改变了结构的大小,如果是,库和调用代码是否同意已设置的选项?
  • ephsat 成员的地址差别很大。 nav_tsat_t 结构在库(大得多)和您的主程序之间具有不同的定义/大小。
  • 请提供minimal reproducible example 并选择标记为cc++ 而不是两者都标记

标签: c++ c linux segmentation-fault


【解决方案1】:

我刚刚发现了问题。我刚刚意识到,我使用了两个不同版本的 rtklib.h。这导致 rnxctr_t 结构的大小不同。

所以最后这只是我的愚蠢,但无论如何感谢您的帮助 cmets。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多