C 程序接收信号 SIGTRAP,每 3 次尝试运行良好

标签 c csv dynamic struct breakpoints

<分区>

我正在用 C 语言编写一个“谁想成为百万富翁”游戏,其中包括 SDL。 我已经开发了 SDL 图形并分别进行了数据处理。 后者是我遇到的问题。

它得到一个大约 5000 行长的 .csv 文件,并借助动态分配的内存将细节放入结构中。 然后它被打印到控制台。 但是,它每 3 次左右才起作用。 其他时候,程序会卡住。 尝试调试,它说:

Program received signal SIGTRAP, Trace/breakpoint trap.

认为我将问题缩小到这部分:

while ((read = getline(&line, &n, kerdes)) != -1) {
    sp = p = line;
    field = 0;
    // The below line triggers the signal
    questions[cnt] = (Question*) malloc(sizeof(Question));

    // Cuts
    while (*p != '\0') {
        if (*p == ',') {
            *p = 0;

            if (field == 0) questions[cnt]->nth = atoi(sp);
            if (field == 1) questions[cnt]->question_to = strdup(sp);
            if (field == 2) questions[cnt]->answer_a = strdup(sp);
            if (field == 3) questions[cnt]->answer_b = strdup(sp);
            if (field == 4) questions[cnt]->answer_c = strdup(sp);
            if (field == 5) questions[cnt]->answer_d = strdup(sp);
            if (field == 6) questions[cnt]->answer_r = strdup(sp);
            if (field == 7) questions[cnt]->cat = strdup(sp);

            *p = ',';
            sp = p + 1;
            field++;
        }
        p++;
    }
    cnt++;
}

getline 函数来自 this answer :

size_t getline(char **lineptr, size_t *n, FILE *stream) {
    char *bufptr = NULL;
    char *p = bufptr;
    size_t size;
    int c;

    if (lineptr == NULL) {
        return -1;
    }
    if (stream == NULL) {
        return -1;
    }
    if (n == NULL) {
        return -1;
    }
    bufptr = *lineptr;
    size = *n;

    c = fgetc(stream);
    if (c == EOF) {
        return -1;
    }
    if (bufptr == NULL) {
        bufptr = malloc(128);
        if (bufptr == NULL) {
            return -1;
        }
        size = 128;
    }
    p = bufptr;
    while(c != EOF) {
        if ((p - bufptr) > (size - 1)) {
            size = size + 128;
            bufptr = realloc(bufptr, size);
            if (bufptr == NULL) {
                return -1;
            }
        }
        *p++ = c;
        if (c == '\n') {
            break;
        }
        c = fgetc(stream);
    }

    *p++ = '\0';
    *lineptr = bufptr;
    *n = size;

    return p - bufptr - 1;
}

我做了 - 希望 - 彻底搜索 stackoverflow,但没有成功。

什么可能导致问题?
在我看来,过度索引并不在其背后,并且 free() 使用得很好。

请通过以下链接在 pastebin 上找到整个 .c 文件: Click here

可使用以下链接访问 CSV 文件(非英语):Click here

最佳答案

问题出在getline 代码中,那是非常糟糕的。我将其替换为 POSIX 标准 getline 并且它可以完美运行。问题是这里的 realloc 代码:

p = bufptr;
while(c != EOF) {
    if ((p - bufptr) > (size - 1)) {
        size = size + 128;
        bufptr = realloc(bufptr, size);
        if (bufptr == NULL) {
            return -1;
        }
    }
    *p++ = c;
    if (c == '\n') {
        break;
    }
    c = fgetc(stream);
}

realloc 可以(很可能)返回一个指向缓冲区的指针,但是p 将指向旧缓冲区,因此行 *p++ = c; 将具有未定义的行为

I have now provided a (hopefully) fixed version of that getline implementation in my answer to the getline question.

关于C 程序接收信号 SIGTRAP,每 3 次尝试运行良好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47228046/

相关文章:

c - ICMP 指针和校验和

scala - 使用 scala 在 Spark 应用程序中构建倒排索引

Python - 使用 2 种定义类型处理 csv

动态改变端点 Camel

c - 使用 OSR 驱动程序加载程序加载驱动程序错误

c - 有没有办法在 C 中打印出变量/指针的类型?

python - 列名和相应的数据在 python 中不匹配

javascript - 如何在AG-Grid中设置列的动态字段?

C++:动态 .so 库中的类

c - 类型转换为 unsigned char 并乘以变量