2012-01-03 1 views
0

Objective-Cアプリケーションで実行されているCコードが少しあります。私はインターネットからこのコードを奪った。事前設定のCコード保持文字

static void extract_app_name(const char *all_arguments, char **app_name) { 
    char *full_path, *app_end, *app_begin; //, *app_name_temp; 
    size_t diff; 

    if (all_arguments == NULL || app_name == NULL) { 
     return; 
    } 

    full_path = (char*)all_arguments + sizeof(int); 

    app_end = strcasestr(full_path, ".app"); 
    if (app_end == NULL) { 
     app_begin = strrchr(full_path, '/'); 
     if (app_begin != NULL) {     
      *app_name = malloc(app_begin+1); 
      *app_name = strdup(app_begin+1); 
     } else {     
      *app_name = strdup(full_path); 
     } 
    } else {    
     app_begin = app_end; 
     while (*(--app_begin) != '/') {} 
     diff = app_end - app_begin; 
     char *app_name_temp[diff]; // = malloc(diff); 
     *app_name_temp = malloc(diff); 
     *app_name = malloc(diff); 
     strncpy(*app_name_temp, app_begin+1, diff-1); 
     app_name_temp[diff]='\0'; 
     app_name = strcpy(*app_name, *app_name_temp); 
    } 
} 

このコードの目的は、フルパスからアプリケーション名を抽出することです。アプリケーションに.appという名前が付いている場合は、.appの処理が何であってもその名前が引き出されます。

たとえば、次のよう:この

extract_app_name("/Applications/Google Chrome.app/Contents/Versions/16.0.912.63/Google Chrome Helper.app/Contents/MacOS/Google Chrome Helper", &app_name); 
NSLog(@"First App is: %s", app_name); 

extract_app_name("/System/Library/Frameworks/QuickLook.framework/Resources/quicklookd.app/Contents/MacOS/quicklookd", &app_name); 
NSLog(@"Next App is: %s", app_name); 

extract_app_name("/System/Library/CoreServices/Dock.app/Contents/XPCServices/com.apple.dock.extra.xpc/Contents/MacOS/com.apple.dock.extra", &app_name); 
NSLog(@"Next App is: %s", app_name); 

extract_app_name("/Applications/Tiny", &app_name); 
NSLog(@"Next App is: %s", app_name); 

万一出力:

First App is: Google Chrome 
Next App is: quicklookd 
Next App is: Dock 
Next app is: Tiny 

は一般的に、それが正しいのです。しかし、アプリを4〜5回連続して実行すると、出力がうまくいかないことがあります。場合によってはquicklookdを出力する2番目のアプリは、実際にはquicklookdomeをダンプします(最初のアプリ名の一部を保持します)。

私は変数が正しく初期化されておらず、メモリ内のその場所に既にあるものを保持していないと思われます。私はちょうどそれをピンポイントするのに十分なCを知らない。ここで

+0

関数を呼び出すたびにメモリリークを避けるために 'free(app_name)'を呼び出すようにしてください。これは、関数が 'malloc'を使用して文字列を格納するメモリを取得するためです。 – v1Axvw

+1

'* app_name = malloc(app_begin + 1);という行は、いくつかの理由から意味をなさない。ポインタをサイズとして 'malloc'に渡しています。また、' * app_name'に値を代入した直後に 'strdup'によって返された値を代入しています。 – AusCBloke

答えて

0

それは、固定され、簡略化されている:あなたのコードは、メモリリークが発生している

static void extract_app_name(const char *all_arguments, char **app_name) { 
     char *full_path, *app_end, *app_begin; //, *app_name_temp; 
     size_t diff; 

     if (all_arguments == NULL || app_name == NULL) { 
      return; 
     } 

     full_path = (char*)all_arguments + sizeof(int); 

     app_end = strcasestr(full_path, ".app"); 
     if (app_end == NULL) { 
      app_begin = strrchr(full_path, '/'); 
      if (app_begin != NULL) 
       *app_name = strdup(app_begin+1); 
      else 
       *app_name = strdup(full_path); 
     } else { 
      app_begin = app_end; 
      while (*(--app_begin) != '/') {} 
      diff = app_end - app_begin; 
      *app_name = malloc(diff);   
      strncpy(*app_name, app_begin+1, diff-1); 
     } 
    } 

注意。 extract_app_nameへの発信者は、完了したら文字列を解放する必要があります。

+0

これらの変更を行っても、同じ動作が発生します。 – bugfixr

関連する問題