使用 Valgrind 调试我的程序

Debugging my program with Valgrind

我的程序运行正常,但是当我用 Valgrind 分析它时出现错误:

==18865== Syscall param execve(argv) points to unaddressable byte(s)
==18865==    at 0x513DCF7: execve (syscall-template.S:84)
==18865==    by 0x513E50A: execvpe (execvpe.c:146)
==18865==    by 0x406FE3: fork_pipes2 (util.c:1338)
==18865==    by 0x40376A: execute_pipeline (main.c:282)
==18865==    by 0x403E53: run_cmd (main.c:327)
==18865==    by 0x403E53: command (main.c:668)
==18865==    by 0x402722: main (main.c:870)
==18865==  Address 0x589bb88 is 0 bytes after a block of size 8 alloc'd
==18865==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==18865==    by 0x403E07: run_cmd (main.c:315)
==18865==    by 0x403E07: command (main.c:668)
==18865==    by 0x402722: main (main.c:870)
==18865==

违规行是

pipe->data = malloc(sizeof(char*));

上下文中的代码是

int run_cmd(char *cmd) {
    struct str_list *chunks = list_split(cmd, '|');
    struct pipeline *pipe = malloc(chunks->size * sizeof * pipe); 
    pipe->data =  malloc(sizeof(char*));
    int i=0;
    for (i= 0; i < chunks->size; i++) { /* TODO: factor out */;
        int j=0;
        for (j = 0; j < 1; j++) {
            pipe[i].data[j] = strdup(chunks[i].argv[j]);
        }
    }
    pipe->size = i;
    int status = execute_pipeline(pipe);
    return status;
}

我的数据结构:

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

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

你能告诉我为什么会出现这个错误吗?我想我没有正确使用 malloc。

这个分配和这些循环是错误的:

pipe->data =  malloc(sizeof(char*));
for (i= 0; i < chunks->size; i++) { /* TODO: factor out */;
    int j=0;
    for (j = 0; j < 1; j++) {
        pipe[i].data[j] = strdup(chunks[i].argv[j]);
    }
}

分配只为第一个管道data成员分配内存,不为数组中的其他成员分配内存。你应该在外循环内部分配,比如

for (i= 0; i < chunks->size; i++) {
    pipe[i].data = malloc(sizeof(char *) * 1);

    for (int j = 0; j < 1; j++) {
        pipe[i].data[j] = strdup(chunks[i].argv[j]);
    }
}