2017-01-14 9 views
1

機能RenameSubs()で、私は、デバッグしようとしたとき、私はなぜ私は理解していないコードCのmalloc関数のセグメンテーションフォールト

subsdir[i] = (char*)malloc((GetStringSize(moviesdir[i]) + 1 + 4) * sizeof(char)); 

のこのラインでセグメンテーションフォールトを取得する - あなたは説明することができますか?

int main() 
{ 
    int number; 
    char *mainDirectory = NULL,**names = NULL; 

    printf("Give the movies directory: "); 
    mainDirectory = ReadMainDirectory(); 

    if(GetFiles(&mainDirectory,&names,&number) != 0) 
    { 
     RenameSubs(number,mainDirectory,names); 
     system("PAUSE"); 
     return 1; 
    } 

    system("PAUSE"); 
    return 0; 
} 

char* ReadMainDirectory() 
{ 
    char *dir,c; 
    int size = 1; 

    dir = (char*)malloc(size+1); 
    dir[size-1] = '\0'; 

    while((c = getchar()) != '\n') 
    { 
     dir[size-1] = c; 
     size++; 

     dir = (char*)realloc(dir,size+1); 
     dir[size-1] = '\0'; 
    } 

    return dir; 
} 

int GetFiles(char **dir,char ***names,int *number) 
{ 
    struct dirent *dp; 
    DIR *fd; 

    if ((fd = opendir(*dir)) == NULL) 
    { 
     printf("Can't open directory %s!\n",*dir); 
     return 0; 
    } 

    *number = 0; 

    *names = (char**)malloc(((*number)+1) * sizeof(char*)); 

    while ((dp = readdir(fd)) != NULL) 
    { 
     if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) 
     { 
      continue; 
     } 

     (*names)[*number] = strdup(dp->d_name); 

     (*number)++; 

     *names = (char**)realloc(*names,((*number)+1) * sizeof(char*)); 
    } 

    closedir(fd); 

    return 1; 
} 

int GetStringSize(char *string) 
{ 
    int size = 0; 

    while(string[size] != '\0') 
    { 
     size++; 
    } 

    return size; 
} 

int StringEndsWith(char* string,char* extension) 
{ 
    int size; 
    char *strextension = NULL; 

    size = GetStringSize(string); 

    strextension = (char*)malloc(5 * sizeof(char)); 

    strextension[0] = string[size-4]; 
    strextension[1] = string[size-3]; 
    strextension[2] = string[size-2]; 
    strextension[3] = string[size-1]; 
    strextension[4] = '\0'; 

    if(strcmp(strextension,extension) == 0) 
    { 
     return 1; 
    } 

    return 0; 
} 

void RenameSubs(int number,char* mainDir,char** filenames) 
{ 
    int i,mainDirSize,movieDirSize[number],moviesdirnumber,subsdirnumber,j,y; 
    char **moviesdir = NULL,**subsdir = NULL,**subsdest = NULL,**moviesdirfilenames = NULL,**subsdirfilenames = NULL,*moviesname = NULL; 

    moviesdir = (char**)malloc(number * sizeof(char*)); 

    mainDirSize = GetStringSize(mainDir); 

    for(i=0;i<number;i++) 
    { 
     movieDirSize[i] = mainDirSize + 1 + GetStringSize(filenames[i]); 

     moviesdir[i] = (char*)malloc((movieDirSize[i]+1) * sizeof(char)); 

     strcpy(moviesdir[i],mainDir); 
     strcat(moviesdir[i],"\\"); 
     strcat(moviesdir[i],filenames[i]); 

     GetFiles(&moviesdir[i],&moviesdirfilenames,&moviesdirnumber); 

     subsdir[i] = (char*)malloc((GetStringSize(moviesdir[i]) + 1 + 4) * sizeof(char)); 

     strcpy(subsdir[i],moviesdir[i]); 
     strcat(subsdir[i],"\\"); 
     strcat(subsdir[i],"Subs"); 

     GetFiles(&subsdir[i],&subsdirfilenames,&subsdirnumber); 

     subsdest[i] = (char*)malloc((GetStringSize(subsdir[i]) + GetStringSize(subsdirfilenames[0]) + 1) * sizeof(char)); 

     strcpy(subsdest[i],subsdir[i]); 
     strcat(subsdest[i],"\\"); 
     strcat(subsdest[i],subsdirfilenames[0]); 

     for(j=0;j<moviesdirnumber;j++) 
     { 
      if(StringEndsWith(moviesdirfilenames[j],".mkv") || StringEndsWith(moviesdirfilenames[j],".mp4") || StringEndsWith(moviesdirfilenames[j],".avi")) 
      { 
       moviesname = (char*)malloc((GetStringSize(moviesdirfilenames[j]) - 4 + 1) * sizeof(char)); 

       for(y=0;y<(GetStringSize(moviesdirfilenames[j]) - 4);y++) 
       { 
        moviesname[y] = moviesdirfilenames[j][y]; 
       } 

       moviesname[y] = '\0'; 

       break; 
      } 
     } 
    } 
} 
+0

'GetStringSize'の目的は何ですか?標準の 'strlen'の何が問題なのですか?また、[mallocの結果のキャストに関するこのディスカッション](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)を読むことをお勧めします。 –

+0

私はコードを書く時間がありました。私はstrlenを忘れていたので、関数を自分で書いていました。なぜ、それを使用しなかったのですか。リンクがありがとうございます。 – Jaspar

+0

'StringEndsWith(char * string、char * extension)'は '{return!strcmp(string + strlen(string) - strlen(extension)、extension);と書くことができます。 } '。 – DyZ

答えて

0

ポインタを初期化せずにポインタの配列を使用しています。それを初期化する。

ループにおいて

subsdir[i] = malloc((GetStringSize(moviesdir[i]) + 1 + 4) * sizeof(char)); 

これにより、第2のステップです。最初にあなたは初期化する必要があります

+0

私はすべてのポインタをNULLで初期化しました。 – Jaspar

+0

'subsdir = malloc(sizeof(char)* number);'は 'subsdir = malloc(sizeof(char *)* number);でなければなりません; – DyZ

+0

私は今Cの多くを覚えていません。二重ポインタで初期化される...疑問に思ったように答えに行を追加してみてください。 – minigeek

関連する問題