2015-12-22 49 views
-2

我的代碼給glibc錯誤。請別人指出我的錯誤。 此代碼用於標記單詞。我如何使用GDB或任何其他可能有用的工具解決這些問題。下面glibc檢測到outfile:free():無效指針:

#include <stdio.h> 
#include <stdlib.h> 
#include <glib.h> 
#include <string.h> 

struct token 
{ 
    char *token; 
    int length; 
}; 

void freeing(gpointer item) 
{ 
free(((struct token*)item)->token); 
} 


int main(int argc, char* argv[]) 
{ 
    int start1 = 0, start2 = 0, i =0; 

    struct token *tk = NULL; 
    char line[256], *temp = NULL; 

    FILE *fp1 = NULL; 
    FILE *fp2 = NULL; 

    GSList *list = NULL, *iterator = NULL; 
    fp1 = fopen(argv[1], "r"); 
    fp2 = fopen(argv[2], "w+"); 

    if (NULL == fp1) 
    { 
     fprintf(stderr,"cant open %s",argv[1]); 
     return 1; 
    } 

    if (NULL == fp2) 
    { 
     fprintf(stderr,"cant open %s",argv[2]); 
     return 1; 
    }  

    while (1) 
    { 

    if (NULL == fgets(line, 255, fp1)) 
    break; 

    tk = (struct token *)malloc(sizeof(struct token)); 

    start1 = -1; start2 = -1; 

    for(temp = line,i = 0; temp[i] != '\n'; i++) 
    { 
     if ((temp[i] == ',') || (temp[i] == ' ') || (temp[i] == ';') || (temp[i] == '.')) 
     start2 = i; 

     if (start1 == start2) 
     continue; 



    tk->token = strndup(line + (start1+1), start2 - (start1+1)); 
    tk->length = strlen(tk->token); 
    list = g_slist_append(list, tk); 

    start1 = start2;  

    } 

    tk->token = strndup(line + (start1+1), strlen(line)); 
    tk->length = strlen(tk->token); 
    printf("\ntk->length : %d\n",tk->length); 
    list = g_slist_append(list, tk); 


} 


    for (iterator = list; iterator; iterator = iterator->next) 
    { 
    printf("%s -> ",((struct token *)(iterator->data))->token); 
    printf("%d\n",((struct token*)iterator->data)->length); 
    } 

    g_slist_foreach(list, (GFunc)freeing, NULL); 

fclose(fp1); 
fclose(fp2); 

return 0; 

} 
+1

請格式化您的代碼,刪除不必要的強制轉換並將其一致地縮進。 –

+2

'list = g_slist_append(list,tk);'在'for'循環中被重複調用,具有相同的'tk'值。也就是說,您正在多次排隊相同的元素。因此多次釋放相同的標記。所以第一次免費會成功,隨後的免費會導致您顯示的錯誤。請注意,代碼中存在其他錯誤,例如內存泄漏和內存損壞。內存問題的一個好的調試工具是[valgrind](http://valgrind.org/) – kaylum

+0

我爲每個已讀取的新令牌分配新的空間並將其存儲在列表中。這不正確嗎? – Tejas

回答

1

的代碼給出下面的代碼有固定的大問題,而不是在循環中的邏輯錯誤:

for(int i=0, temp = line; temp[i] != '\n'; i++) 
{ 
    ... 
} 

tk->token = strndup(line + (start1+1), strlen(line)); 
tk->length = strlen(tk->token); 
printf("\ntk->length : %d\n",tk->length); 
list = g_slist_append(list, tk); 

建議修復在發佈代碼的大部分問題糾正如下:

增加了對g_slist_free(list);的最終調用,以便將struct token的所有實例返回到堆中。

#define _GNU_SOURCE 
#include <stdio.h> 
#include <stdlib.h> 
#include <glib.h> 
#include <string.h> 

#define MAX_LINE_LEN (256) 

struct token 
{ 
    char *token; 
    int length; 
}; 

void freeing(gpointer item) 
{ 
    free(((struct token*)item)->token); 
} 


int main(int argc, char* argv[]) 
{ 
    if(3 != argc) 
    { // then incorrect number of command line arguments 
     fprintf(stderr, "USAGE: %s <inputfile> <outputfile>\n", argv[0]); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, correct number of command line arguments 

    FILE *fp1 = NULL; 
    FILE *fp2 = NULL; 

    if(NULL == (fp1 = fopen(argv[1], "r"))) 
    { // then fopen failed 
     fprintf(stderr, "fopen for %s for read failed\n", argv[1]); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, fopen successful 

    if(NULL == (fp2 = fopen(argv[2], "w+"))) 
    { // then fopen failed 
     fprintf(stderr, "fopen for %s for write failed\n", argv[2]); 
     fclose(fp1); // cleanup 
     exit(EXIT_FAILURE); 
    } 

    // implied else, fopen successful 



    GSList *list = NULL; 
    GSList *iterator = NULL; 

    char line[ MAX_LINE_LEN ]; 
    struct token *tk = NULL; 
    char *temp = NULL; 

    while (fgets(line, sizeof(line), fp1)) 
    { 

     if(NULL == (tk = malloc(sizeof(struct token)))) 
     { // then malloc failed 
      perror("malloc for struct token failed"); 
      fclose(fp1); 
      fclose(fp2); 
      exit(EXIT_FAILURE); 
     } 

     // implied else, malloc successful 

     size_t start1 = 0; 
     size_t start2 = 0; 

     temp = line; 
     for(size_t i=0; temp[i] != '\n'; i++) 
     { 
      if ((temp[i] == ',') || (temp[i] == ' ') || (temp[i] == ';') || (temp[i] == '.')) 
       start2 = i; 

      if (start1 == start2) 
       continue; 

      tk->token = strndup(line + (start1+1), start2 - (start1+1)); 
      tk->length = (int)strlen(tk->token); 
      list = g_slist_append(list, tk); 

      start1 = start2; 
     } // end for 

     tk->token = strndup(line + (start1+1), strlen(line)); 
     tk->length = (int)strlen(tk->token); 
     printf("\ntk->length : %d\n",tk->length); 
     list = g_slist_append(list, tk); 

    } // end while 


    for (iterator = list; iterator; iterator = iterator->next) 
    { 
     printf("%s -> ",((struct token *)(iterator->data))->token); 
     printf("%d\n",((struct token*)iterator->data)->length); 
    } 

    g_slist_foreach(list, (GFunc)freeing, NULL); 
    g_slist_free(list); 

    fclose(fp1); 
    fclose(fp2); 

    return 0; 

} 
+0

它仍然給glibc.error – Tejas

+0

什麼,確切地說,是錯誤?當使用'glibc'工具時,編譯器的參數變得非常「不尋常」。下面是我在geany編輯器下編譯時使用的gcc:gcc -ggdb -Wall -Wextra -pedantic -Wconversion -std = c99 -c「%f」-I/usr/include/mpi'pkg-config - -cflags glib-2.0'' pkg-config --libs glib-2.0',其中「%f」成爲正在編譯的文件的名稱。注意有幾個back ticks需要在這個評論中不太好顯示 – user3629249

+0

我的理解是你在Ubuntu的linux上。你有沒有像下面這樣下載/安裝'glibc':'sudo apt-get install glibc'?我問,因爲這個代碼編譯沒有任何錯誤對我來說。 – user3629249

相關問題