2016-08-25 44 views
-1

我需要ipv6地址中的最後2列。 (2001:1234:asdd:xeed:212:4b00:61) - >(4b0061)我也需要知道如何釋放ipv6_parser函數的返回值。使用自由變量後分段錯誤返回功能

當我試圖釋放結果時,它被給出「分段錯誤」。

char* ipv6_parser(char* str){ 
    char *ret = malloc(sizeof(str)); 

    ret = str; 
    ret = strtok(ret,":"); 
    int i ; 
    for (i=0;i<5;i++){ 
     ret = strtok(NULL, ":"); 
    } 
    char *last = strtok(NULL, ":"); 
    sprintf(ret,"%s%s",ret,last); 

    return ret; 
} 

int main(){ 
    mtrace(); 

    char *str=strdup("2001:1234:asdd:xeed:212:4b00:61"); 
    char* result = ipv6_parser(str); 
    printf("\nResult - %s\n",result); 
    free(result); 
    free(str); 
return(0); 
} 
+5

'的sizeof(STR)'和'strlen的(STR)'有很大的不同 –

+2

這是毫無意義的了'ret'分配內存,如果你只是要覆蓋在下一個語句中指向該內存的指針。也許你正在尋找'strdup()'? –

+0

使用內存調試器,如[Valgrind](http://valgrind.org/)來幫助您發現問題。 –

回答

1
  • ret = str;不復制字符串,但分配輸入指針本身ret並造成內存泄漏。
  • 您不能使用sizeof(str)來確定字符串的長度。
  • sprintf(ret,"%s%s",ret,last);調用未定義的行爲通過在外包裹的對象之間進行復制。

試試這個:

char* ipv6_parser(const char* str){ 
    char *ret = malloc(strlen(str) + 1); 
    if (ret == NULL){ 
    perror("malloc ret"); 
    return NULL; 
    } 
    char *ret_buffer = ret; /* store where the buffer is to free it after using */ 

    strcpy(ret,str); 
    ret = strtok(ret,":"); 
    int i; 
    for (i=0;i<5;i++){ 
    ret = strtok(NULL, ":"); 
    } 
    char *last = strtok(NULL, ":"); 
    char *final_ret = malloc(strlen(ret) + strlen(last) + 1); 
    if (final_ret == NULL){ 
    perror("malloc final_ret"); 
    free(ret_buffer); 
    return NULL; 
    } 
    sprintf(final_ret,"%s%s",ret,last); 
    free(ret_buffer); 

    return final_ret; 
} 
+0

考慮到OP已經在使用'strdup()',你可以減少'malloc(strlen + 1); strcpy()'raindance。 – EOF

+0

謝謝你的幫助。它正在處理這些代碼。我明白當我遇到這種情況時我需要做什麼。 – Gkan