2016-05-11 9 views
0

私は二度目は、この文が実行されるセグメンテーション違反を得る:このセグメンテーションフォルトをどのようにデバッグできますか?

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

'チャンク= malloc関数(はsizeof(チャンク));' - > 'チャンク= malloc関数(はsizeof(*チャンク));' – BLUEPIXY

+0

また 'チャンク[I] .argv [0] =のmalloc(STRLEN (トークン)* sizeof(char *)+ 1); ':メモリリーク – BLUEPIXY

答えて

1

この行でポインターがあるchunks変数のサイズを、割り当て

chunks = malloc(sizeof(chunks)); 

通常は4または8バイトだけです(32または64ビットシステムの場合)。

str_list構造は、あなたが未定義の動作、最も可能性の高いクラッシュにつながる、割り当てられたメモリの境界外に書き込みますを意味し、それよりも大きくなっています。

は、あなたが最も簡単な例で行われた、2つの フル str_list構造を割り当てる必要があることを意味しており、ループによって判断し、この構造の2つを使用しているように見えます

chunks = malloc(2 * sizeof *chunks); 
関連する問題