0

私はこの機能を持っています:

char * folderFromPath(char *path)
{
  printf("\nentered folderFromPath\n");

  char *token[80];
  int i = 0;  
  const int STR_LEN = 128;
  char str[STR_LEN];
  char *folder;
  folder = malloc(sizeof(path));
  strcpy(folder,"/");

  if (strlen(path) > STR_LEN)
  {
    printf("Warning: strlen(path) > STR_LEN, (%d > %d) in function folderFromPath\n", strlen(path), STR_LEN);
  }
  else
  {
      printf("path: %s\n", path);

    strcpy(str,path);

    token[0] = strtok(str, "/");

    while (token[i]!= NULL)
    {
      i++;
      token[i] = strtok (NULL, "/");
      printf("token[i]: %s, i: %d\n", token[i], i);
    }

    if (folder != NULL)
    {
        int j = 0;
        while (j < (i-1))
        {
              strcat(folder,token[j]);
              strcat(folder,"/");
            j++;
        }

        printf("folder: %s\n", folder);

    }

  } /* else if (strlen(path) < STR_LEN) */

  return folder;

}

その中で、が指すメモリを動的に割り当てていることがわかりますfolder。また、フォルダーが呼び出し元の関数に戻されていることもわかります。この投稿で、呼び出し元の関数で使用された後にポインターを解放することが提案されているのを見ました。それが私がやったことです。呼び出し元の関数は次のとおりです。

void open_activated(GtkWidget *widget, GtkWindow *parent)
{
  GtkSourceLanguage *lang;
  GtkSourceLanguageManager *lm;
  GtkWidget *dialog;
  GtkWidget *tablabel;
  GtkTextBuffer *tbuffer;
  int openTabs = 0;
  char *folder1;
  const gchar *folder2;
  int page = 0;
  char *path;

  page = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook));
  path  = paths[notebookPages[page]];
  folder1 = folderFromPath(path);
  folder2 = folder1;

  dialog = gtk_file_chooser_dialog_new("Open File", parent, GTK_FILE_CHOOSER_ACTION_OPEN,GTK_STOCK_CANCEL,GTK_RESPONSE_CANCEL,GTK_STOCK_OPEN,GTK_RESPONSE_ACCEPT,NULL);
  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(dialog), folder2);
  free(folder1); 

  tbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(txtinput[openedPages]));

  gtk_source_buffer_begin_not_undoable_action(GTK_SOURCE_BUFFER(tbuffer));

  if(gtk_dialog_run(GTK_DIALOG(dialog))== GTK_RESPONSE_ACCEPT)
  {

    ...

  } /* if(gtk_dialog_run(GTK_DIALOG(dialog))== GTK_RESPONSE_ACCEPT) */

  gtk_widget_destroy(dialog);
  changeLabelColor("black");
  gtk_text_buffer_set_modified (gtk_text_view_get_buffer((GTK_TEXT_VIEW(txtinput[openedPages]))), FALSE);

  gtk_source_buffer_end_not_undoable_action(GTK_SOURCE_BUFFER(tbuffer));
  write_config_files();

  verifyPaths();  

}

ファイルを開こうとすると、アプリケーションは中止され、次のステートメントが生成されます。

*** glibc detected *** ./ledit: free(): invalid next size (fast): 0x082a80c8 ***

だから私の質問は、このエラーが何を意味するのか、そしてポインタを適切に解放するために私は別の方法で何をすべきかということです。ありがとう。

4

1 に答える 1

2

主な問題はおそらくこれです。

char * folderFromPath(char *path)
...
folder = malloc(sizeof(path));

が割り当てられているのでsizeof(path)、と同じです。おそらく意図したパス全体ではなく、単一のポインタを保持するのに十分なバイトを割り当てているだけです。sizeof(char*)pathchar*

代わりに試してください:

folder = malloc(strlen(path)+1);

他の問題があるかもしれません。私はあまり詳しく調べていません。folderに渡した後、リターンを正しく解放しているように見えますがgtk_file_chooser_set_current_folder()、なぜそれを割り当てているのかはわかりませんfolder2。文字列をコピーする割り当てを期待している場合(GTK関数はパスの所有権を取得することを期待していますか?)、失望します。strncpy()または同様のものを使用して、文字列の別のコピーを取得する必要があります。

于 2012-06-05T23:38:46.613 に答える