You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

f2c转换C代码调用s_wsfe时cilist成员异常致崩溃

f2c转换后C代码调用s_wsfe时cilist成员异常的排查方案

问题场景

运行f2c转换后的C代码时,调用s_wsfe函数出现崩溃,原因是传入的cilist结构体中cifmt成员在函数内部变为null,但在调用前该成员是正常指向字符串的。

MainFile.C代码

static char fmt_4[] = "This is a very long string...";

static cilist io___94 = { 0, 6, 0, fmt_4, 0 };

printf("io___94.cierr: -%d-\n",io___94.cierr);
printf("io___94.ciunit: -%d-\n",io___94.ciunit);
printf("io___94.ciend: -%d-\n",io___94.ciend);
printf("io___94.cifmt: -%s-\n",io___94.cifmt);
printf("io___94.cirec: -%d-\n",io___94.cirec);

printf("sizeof io___94.cierr: -%lu-\n",sizeof(io___94.cierr));
printf("sizeof io___94.ciunit: -%lu-\n",sizeof(io___94.ciunit));
printf("sizeof io___94.ciend: -%lu-\n",sizeof(io___94.ciend));
printf("sizeof io___94.cifmt: -%lu-\n",sizeof(io___94.cifmt));
printf("sizeof io___94.cirec: -%lu-\n",sizeof(io___94.cirec));

s_wsfe(&io___94);

MainFile打印输出

io___94.cierr: -0-
io___94.ciunit: -6-
io___94.ciend: -0-
io___94.cifmt: -This is a very long string...-
io___94.cirec: -0-

sizeof io___94.cierr: -4-
sizeof io___94.ciunit: -4-
sizeof io___94.ciend: -4-
sizeof io___94.cifmt: -8-
sizeof io___94.cirec: -4-

libf2c中s_wsfe函数代码

int s_wsfe(cilist *a)   /*start*/
#endif
{   int n;
    printf("a->cierr: -%ld-\n",a->cierr);
    printf("ciunit: -%d-\n",a->ciunit);
    printf("ciend: -%ld-\n",a->ciend);
    printf("a->cifmt: -%s-\n",a->cifmt);
    printf("cirec: -%d-\n",a->cirec);

    printf("sizeof a->cierr: -%lu-\n",sizeof(a->cierr));
    printf("sizeof ciunit: -%lu-\n",sizeof(a->ciunit));
    printf("sizeof ciend: -%lu-\n",sizeof(a->ciend));
    printf("sizeof a->cifmt: -%lu-\n",sizeof(a->cifmt));
    printf("sizeof cirec: -%lu-\n",sizeof(a->cirec));

    if(!f__init) f_init();
    f__reading=0;
    f__sequential=1;
    f__formatted=1;
    f__external=1;
    if(n=c_sfe(a)) return(n);
    f__elist=a;
    f__hiwater = f__cursor=f__recpos=0;
    f__nonl = 0;
    f__scale=0;
    f__fmtbuf=a->cifmt;
    f__cf=f__curunit->ufd;
    if(pars_f(f__fmtbuf)<0) err(a->cierr,100,"startio"); //Crash here
    f__putn= x_putc;
    f__doed= w_ed;
    f__doned= w_ned;
    f__doend=xw_end;
    f__dorevert=xw_rev;
    f__donewrec=x_wSL;
    fmt_bg();
    f__cplus=0;
    f__cblank=f__curunit->ublnk;
    if(f__curunit->uwrt != 1 && f__nowwriting(f__curunit))
        err(a->cierr,errno,"write start");
    return(0);
}

s_wsfe打印输出

a->cierr: -25769803776-
ciunit: -0-
ciend: -4323035328-
a->cifmt: -(null)-
cirec: -1-

sizeof a->cierr: -8-
sizeof ciunit: -4-
sizeof ciend: -8-
sizeof a->cifmt: -8-
sizeof cirec: -4-

cilist结构体定义(来自f2c.h)

/*external read, write*/
typedef struct
{   flag cierr;
    ftnint ciunit;
    flag ciend;
    char *cifmt;
    ftnint cirec;
} cilist;

核心问题分析

从两次打印的sizeof结果可以明确:cilist结构体的内存布局在你的代码和libf2c库中不一致。你的代码中cierr和ciend是4字节,而libf2c中这两个成员是8字节,导致传递指针后,libf2c访问成员时偏移错误,a->cifmt实际指向了结构体内存中的无效位置,因此显示为null,其他成员的值也完全错乱。

排查方向

  1. 统一flag和ftnint的typedef定义
    检查你的代码和libf2c使用的f2c.h中,这两个类型的定义是否完全一致。比如flag可能在libf2c中被定义为long(8字节),但你的代码中是int(4字节),直接导致结构体成员的大小和偏移错位。

  2. 统一编译架构
    确认你的代码和libf2c库是否都是32位或64位编译,混合架构会导致指针、长整型的大小差异,破坏结构体布局。

  3. 验证头文件一致性
    确保MainFile.C包含的是和libf2c完全相同版本的f2c.h,没有自定义或修改过结构体定义,也没有包含其他冲突的头文件。

  4. 检查结构体内存偏移
    在MainFile中打印每个成员的地址,在s_wsfe中也打印对应成员的地址,对比偏移是否一致:

    // 在MainFile中添加
    printf("&io___94.cierr: %p\n", &io___94.cierr);
    printf("&io___94.ciunit: %p\n", &io___94.ciunit);
    printf("&io___94.ciend: %p\n", &io___94.ciend);
    printf("&io___94.cifmt: %p\n", &io___94.cifmt);
    printf("&io___94.cirec: %p\n", &io___94.cirec);
    
    // 在s_wsfe中添加
    printf("&a->cierr: %p\n", &a->cierr);
    printf("&a->ciunit: %p\n", &a->ciunit);
    printf("&a->ciend: %p\n", &a->ciend);
    printf("&a->cifmt: %p\n", &a->cifmt);
    printf("&a->cirec: %p\n", &a->cirec);
    

    如果偏移不同,必然是结构体定义不匹配导致的。

内容的提问来源于stack exchange,提问作者ez4nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:55:23