2016-05-12 4 views
1

Моя программа работает правильно, но когда я анализирую его с 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 правильно.

+0

'sizeof * pipe' в порядке, но сбивает с толку. – MikeCAT

+0

Вы присвоили некоторые данные 'pipe [0] .data'. ('pipe-> data' =' (* pipe) .data' = 'pipe [0] .data') Почему бы не назначить' pipe [1] .data' и выше? – MikeCAT

+0

@MikeCAT Я тестирую массив только с одним элементом. Есть много счетчиков, и я еще не получил все счетчики. Поэтому я тестирую только один элемент. Но я могу получить правильный вывод для более длинного конвейера, например. 'ls | wc', который имеет два элемента. Я выполняю команды, делая системные вызовы 'fork' и' exec'. – Montao

ответ

1

Такое распределение и эти петли являются неправильными:

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]); 
    } 
} 
+0

Но я все еще получаю сообщение об ошибке 'pipe [i] .data = malloc (sizeof (char *) * 1)'. 'Адрес 0x589bce8 равен 0 байтам после блока размера 8 alloc'd' – Montao

Смежные вопросы