我在运行下面的代码时遇到了分段错误。
它基本上应该读取一个超过3m行的.csv文件,然后做其他事情(与问题无关),但是在207746次迭代之后,它返回一个分段错误。如果我去掉p = strsep(&line,"|");并打印整个line它将打印>3m行。

int ReadCSV (int argc, char *argv[]){

    char *line = NULL, *p;
    unsigned long count = 0;

    FILE *data;
    if (argc < 2) return 1;
    if((data = fopen(argv[1], "r")) == NULL){
        printf("the CSV file cannot be open");
        exit(0);
    }


    while (getline(&line, &len, data)>0) {

        p = strsep(&line,"|");

        printf("Line number: %lu \t p: %s\n", count, p);
        count++;
    }

    free(line);
    fclose(data);

    return 0;
}

我想这和内存分配有关,但不知道怎么解决。

最佳答案

getlinestrsep的组合通常会导致混淆,因为这两个函数都会更改作为初始参数通过指针传递它们的指针。如果再次将已通过strsep的指针传递到getline,则在第二次迭代中会有未定义行为的风险。
考虑一个例子:getlineline分配101个字节,并在其中读取100个字符串。注意len现在设置为101。您可以调用strsep,它在字符串的中间找到'|',因此它将line指向以前的line+50。现在您再次呼叫getline。它看到另一个100个字符的行,并得出结论,可以将其复制到缓冲区中,因为len仍然是101。但是,由于line现在指向缓冲区的中间,因此写入100个字符成为未定义的行为。
在调用line之前复制strsep

while (getline(&line, &len, data)>0) {
    char *copy = line;
    p = strsep(&copy, "|");
    printf("Line number: %lu \t p: %s\n", count, p);
    count++;
}

现在,传递给linegetline在循环迭代之间被保留。

10-04 21:15
查看更多