【问题标题】:How can I debug this segmentation fault?如何调试此分段错误?
【发布时间】:2016-09-07 09:41:16
【问题描述】:

此语句第二次运行时出现段错误:

chunks[i].argv[0] = malloc( strlen(token) * sizeof(char *) + 1 );

上下文中的代码是:

/* TODO: modify str_split to do the copying of its input string if it needs to (e.g. if it uses strtok on it), and return a struct that has the number of "chunks" it split out and the list of chunks. */
struct str_list *list_split(char *a_str, const char a_delim) {
    char **result = 0;
    char **result2 = 0;

    size_t count = 0;
    char *tmp = a_str;
    char *last_comma = 0;

    size_t count2 = 0;
    char *tmp2 = a_str;
    char *last_space = 0;

    char delim[2];
    delim[0] = a_delim;
    delim[1] = 0;
    struct str_list *chunks = NULL;
    /* Count how many elements will be extracted. */
    while (*tmp) {
        if (a_delim == *tmp) {
            count++;
            last_comma = tmp;
        }
        tmp++;
    }

    /* Add space for trailing token. */
    count += last_comma < (a_str + strlen(a_str) - 1);

    /* Add space for terminating null string so caller
       knows where the list of returned strings ends. */
    count++;

    result = malloc(sizeof(char *) * count);
    chunks = malloc(sizeof(chunks));

    //chunks.size = malloc(sizeof(int));
   // counter = (int) count + 1;
    //chunks->size = counter;

    if (result == NULL) {
        printf("Error allocating memory!\n"); //print an error message
        return chunks;; //return with failure
    }

    if (result) {
        size_t idx = 0;
        char *token = strtok(a_str, delim);
        int i = 0;
        while (token) {
            assert(idx < count);
            *(result + idx++) = strdup(token); /* memory leak! how to free() */;
            token = strtok(0, delim);;
        }
        assert(idx == count - 1);
        *(result + idx) = 0;
    }

    chunks->size = (int) count;
    chunks->argv = alloc_argv((unsigned) chunks->size);

    for (int i = 0; i < 2; i++) { //count is wrong
        while (*tmp2) {
            if (' ' == *tmp2) {
                count2++;
                last_space = tmp2;
            }
            tmp2++;
        }

        char* token = strtok(result[i], " ");
        while (token) {
            printf("token: %s\n", token);
            printf("size: %d\n", chunks->size);
            printf("result: %s\n", result[i]);
            printf("i: %d\n", i);
            chunks[i].argv[0] = malloc( strlen(token) * sizeof(char *) + 1 );
            chunks[i].argv[0] = strdup(token);;
            token = strtok(0, " ");
        }

    }

    return chunks;
}

我的调试器没有说什么有趣的东西。你能看出什么是错的,应该怎么做吗?对上述函数的调用是:

int run_cmd(const char *cmd) {
    struct str_list *chunks = list_split(cmd, '|');
    struct pipeline *pipe = alloc_pipeline(2); //size is the number of pipelines
    for (int i = 0; i < 2; i++) {
        printf("i %d", i);
        for (int j = 0; j < 1; j++) {
            pipe[i].data[j] = chunks[i].argv[j];
        }
    }
    int status = execute_pipeline(pipe);
    // free_pipeline(pipe);
    // free_str_list(chunks);
    return status;
}

我的结构的定义是

struct str_list {
    char *name;
    int size;
    char **argv;

};
struct pipeline {
    char *name;
    int size;
    char **data;
};

【问题讨论】:

  • chunks = malloc(sizeof(chunks)); --> chunks = malloc(sizeof(*chunks));
  • 还有chunks[i].argv[0] = malloc( strlen(token) * sizeof(char *) + 1 );:内存泄漏

标签: c debugging segmentation-fault


【解决方案1】:

这一行

chunks = malloc(sizeof(chunks));

这分配了 chunks 变量的大小,它是一个指针,通常只有 4 或 8 个字节大(取决于您使用的是 32 位还是 64 位系统)。

str_list 结构大于该结构,这意味着您将写入超出分配内存的范围,从而导致未定义的行为并很可能导致崩溃。

从循环来看,你似乎使用了两个这种结构,这意味着你需要分配两个 full str_list 结构,这是最简单的,例如

chunks = malloc(2 * sizeof *chunks);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2013-01-06
    • 2013-05-19
    • 2012-01-06
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多