首页 > 解决方案 > strtol()/atol() 导致分段错误

问题描述

我的问题是这样的:

#define MAX_LINE_LENGTH 100
#define MAX_RESOURCES_NUM 150
#define MAX_REQUESTS_NUM 150
#define MAX_REPAIRS_NUM 150
struct resource {
    long ID;
    char* name;
    long qty;
    sem_t freeResources;
};
struct request {
    long licensenum;
    long time;
    long repcount;
    long *repIDarr;
};
struct repair {
    long ID;
    char* name;
    long hours;
    long rescount;
    long *resIDarr;
};
struct resource* resarr[MAX_RESOURCES_NUM];
struct request* reqarr[MAX_REQUESTS_NUM];
struct repair* reparr[MAX_REPAIRS_NUM];
int timevar, threadcount;
//Func declarations
int main(int argc, char* argv[]){
    FILE *resfile, *reqfile, *repfile;
    char line[MAX_LINE_LENGTH], *refer;
    int i = 0;
    timevar = 0;
    threadcount=0;
    if(argc < 4) { 
        printf("Not enough arguments!");
        return 0;
    }
    if((resfile = fopen(argv[1], "r")) == NULL || (repfile = fopen(argv[2], "r")) == NULL || (reqfile = fopen(argv[3], "r")) == NULL){
        perror("Open file failed"); 
        return 0;
    }

    //Initialize resources
    while(fgets(line, 100, resfile) != NULL){
        char* token;
        refer = line;
        token = strsep(&refer, "\t");
        long ID = atoi(token);
        char* name = strsep(&refer, "\t");
        token = strsep(&refer, "\t");
        if(token = NULL){
            printf("X\n");
            return 0;
        }
        long qty = atol(token);
    }
    fclose(resfile);
    fclose(reqfile);
    fclose(repfile);
    return 0;
}

这只是代码的一部分,足以重现问题。

我有一个名为 resources.txt 的 txt 文件:

13  car lift    8
17  front alignment 2
03  headlights adjust   2
10  oil drain   4
23  computerized check  2
35  pneumatic drive 4
40  ceiling winch   2
99  John Smith  1
29  air compressor  1
66  flats tub   1
88  paint gun   1

strsep()我用by分隔任何行TAB

问题是我一运行程序就会遇到分段错误。

当我删除这一行时:

long qty = atol(token);

在 main 结束时,我没有收到错误消息。

我找不到是什么原因造成的。

最奇怪的是,当我在我的个人计算机上运行该程序时,它运行良好(在 CentOS 上),但是当我在我的大学计算机(使用相同的 CentOS)上运行它时,它向我显示了错误。

有任何想法吗?

标签: cmemorysegmentation-fault

解决方案


  if(token = NULL){

不符合您的期望。

将其更改为

  if (token == NULL) {

为了不再踏入这个“愚蠢的”;) 陷阱,您可能想从现在开始考虑使用“ Yoda-Conditions ”,即将“常数”放在左边,如下所示:

  if (NULL == token) {

因为如果你会做

  if (NULL = token) {

编译器会大量抱怨。

而且,顺便说一句,如果您使用单步调试器跟踪代码,您很可能很快就会注意到这个错误。


推荐阅读