如何调试此分段错误?

时间:2016-05-11 19:44:24

标签: c debugging segmentation-fault

我在第二次发表声明时遇到了段错误:

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;
};

1 个答案:

答案 0 :(得分:1)

这一行

chunks = malloc(sizeof(chunks));

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

str_list结构大于此值,这意味着您将写出已分配内存的范围,导致未定义的行为,并且很可能是崩溃。

你似乎正在使用这个结构中的两个,从循环判断,这意味着你需要分配两个完整的 str_list结构,这是最简单的结果。

chunks = malloc(2 * sizeof *chunks);