2012-06-05 3 views
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. Вы также можете увидеть, что папка возвращается вызывающей функции. Я видел in this post, где было предложено освободить указатель после его использования в вызывающей функции. Вот что я сделал. Вот функция вызова:

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 *** 

Так что мой вопрос, что делает эта ошибка означает, и что я должен делать иначе правильно освободить указатель? Благодарю.

ответ

2

Основная проблема, вероятно, в этом.

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

Вы направляете sizeof(path), которая является таким же, как sizeof(char*), так как path является char*. Вы выделяете достаточное количество байтов для хранения одного указателя, а не всего пути, который, вероятно, является тем, что вы намеревались.

Попробуйте вместо этого:

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

Там вполне могут быть и другие проблемы; Я не очень внимательно смотрел. Кажется, что вы правильно освобождаете ответ folder после передачи его gtk_file_chooser_set_current_folder(), хотя я не знаю, почему вы назначаете его folder2. Если вы ожидаете, что это задание будет скопировать строку (функция GTK ожидает получить право собственности на путь?), Вы будете разочарованы; вам нужно будет взять отдельную копию строки, используя strncpy() или что-то подобное.

+0

спасибо, что был. Теперь у меня нет сбоев при открытии файлов, где до того, как я все время сталкивался с авариями. Я изучаю. Причина, по которой я назначала папку1 в папку2, заключалась в том, чтобы использовать ее в виде, ожидаемом с помощью gtk_file_chooser_set_current_folder(). Это был шаг устранения неполадок, который был растяжкой, но я не знал, что еще попробовать. Теперь, когда я сделал внесенное изменение, я вижу, что это не нужно. Еще раз спасибо. – nomadicME