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

Cygwin栈转储错误求助:打印Company结构体时程序崩溃

问题描述

我正在开发一个项目,需要打印搜索到的结构体,但执行打印操作时,仅完成首次输出程序就退出,并抛出错误:cygwin_exception::open_stackdumpfile: Dumping stack trace。我查询得知该错误通常与动态内存问题相关,但据我所知,我仅读取并打印已有数据,未进行内存新增操作,因此疑惑为何出现该问题。即使手动指定打印结构体内容,仍出现相同错误。


打印函数

void printCompany(Companies companies, int i) {
    printf("\nNif: %d", companies.companies[i].Nif);
    printf("\nName: %s", companies.companies[i].name);
    printf("\nCategory: %s", companies.companies[i].categories);
}

结构体定义

#define COMPANY_INITIAL_SIZE 20
#define SEARCHES_INITIAL_SIZE 20
#define ACTIVITIES_INITIAL_SIZE 20

#define TEXT_MAX_SIZE 200
#define NAME_MAX_SIZE 50
#define EMAIL_MAX_SIZE 50
#define TITLE_MAX_SIZE 50
#define STREET_MAX_SIZE 70
#define LOCATION_MAX_SIZE 70

#define NIF_MIN_SIZE 100000000
#define NIF_MAX_SIZE 999999999

enum category {
    microCompany = 1, pmeCompany, macroCompany
};

enum state {
    inactive, active
};

enum searchCamp {
    nif, businessArea, nameLocation
};

typedef struct {
    char title[TITLE_MAX_SIZE];
    char text[TEXT_MAX_SIZE];
    char userName[NAME_MAX_SIZE];
    char userEmail[EMAIL_MAX_SIZE];
} Coment;

typedef struct {
    int nota;
    char userName[NAME_MAX_SIZE];
    char userEmail[EMAIL_MAX_SIZE];
} Rating;

typedef struct {
    int Nif;
    char name[NAME_MAX_SIZE];
    enum category categories;
    int businessAreaCode;
    enum state states;
    char street[STREET_MAX_SIZE];
    char location[LOCATION_MAX_SIZE];
    int postalCode;
    int nComents;
    Coment coments;
    int nRating;
    Rating ratings;
} Company;

typedef struct {
    int counter, size;
    Company *companies;
} Companies;

void freeCompanies(Companies *);
void loadCompanyFile(Companies *, char*);
void saveCompanyFile(Companies *, char *);
void insertCompanies(Companies*);
void expandCompanySize(Companies *);
void searchNifCompanies(Companies);
//void printCompany(Company);
void printCompany(Companies,int);

调用打印函数的相关函数

/**
 * @brief 查找匹配NIF的公司
 * @param companies Companies结构体
 * @param nif 公司唯一NIF值
 * @return 成功则返回公司索引,失败返回-1
 */
int searchNifCompany(Companies companies, int nif) {
    int i;
    for (i = 0; i < companies.counter; i++) {
        if (companies.companies[i].Nif == nif) {
            return i;
        }
    }
    return -1;
}

/**
 * @brief 处理NIF搜索逻辑
 * @param companies Companies结构体
 * @return 
 */
void searchNifCompanies(Companies companies) {
    int company, nif;

    nif = getInt(NIF_MIN_SIZE, NIF_MAX_SIZE, "\nNIF[9 digits]: ");
    company = searchNifCompany(companies, nif);

    if (company != -1) {
        //printCompany(companies.companies[company]);
        printCompany(companies, company);
    } else {
        puts("该公司不存在。");
    }
}

手动打印结构体的代码

Companies companies;

int main() {
    
    loadCompanyFile(&companies, COMPANIES_FILE_NAME);

    mainMenu();
    
    printf("\nNif: %d", companies.companies[1].Nif);
    printf("\nName: %s", companies.companies[1].name);
    printf("\nCategory: %s", companies.companies[1].categories);
    
    saveCompanyFile(&companies, COMPANIES_FILE_NAME);
    freeCompanies(&companies);
    return (EXIT_SUCCESS);
}

问题根源与解决方法

核心错误:枚举类型用字符串格式符输出

打印代码中这一行是直接触发错误的原因:

printf("\nCategory: %s", companies.companies[i].categories);

categories是enum category类型,本质是整数,但你用了%s(字符串格式符),printf会把枚举的整数值当成内存地址去读取字符串,直接访问非法内存,触发段错误,也就是你看到的cygwin栈转储。

修复方式

给枚举值做字符串映射,新增一个辅助函数:

const char* getCategoryName(enum category cat) {
    switch(cat) {
        case microCompany: return "微型企业";
        case pmeCompany: return "中小企业";
        case macroCompany: return "大型企业";
        default: return "未知类型";
    }
}

然后修改打印函数:

void printCompany(Companies companies, int i) {
    printf("\nNif: %d", companies.companies[i].Nif);
    printf("\nName: %s", companies.companies[i].name);
    printf("\nCategory: %s", getCategoryName(companies.companies[i].categories));
}

其他潜在问题修复

  1. 结构体传值的副本隐患:searchNifCompanies和searchNifCompany都传结构体值,会生成副本,若原结构体的堆内存被释放,副本指针会变成野指针。建议改成传指针:
int searchNifCompany(Companies *companies, int nif) {
    int i;
    for (i = 0; i < companies->counter; i++) {
        if (companies->companies[i].Nif == nif) {
            return i;
        }
    }
    return -1;
}

void searchNifCompanies(Companies *companies) {
    int company, nif;

    nif = getInt(NIF_MIN_SIZE, NIF_MAX_SIZE, "\nNIF[9 digits]: ");
    company = searchNifCompany(companies, nif);

    if (company != -1) {
        printCompany(*companies, company);
    } else {
        puts("该公司不存在。");
    }
}
  1. 数组越界检查:手动打印companies.companies[1]时,要确保companies.counter > 1,避免访问超出数组范围的内存:
if (companies.counter > 1) {
    printf("\nNif: %d", companies.companies[1].Nif);
    printf("\nName: %s", companies.companies[1].name);
    printf("\nCategory: %s", getCategoryName(companies.companies[1].categories));
} else {
    puts("没有足够的公司数据。");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 17:10:55