2014-10-20 82 views
-1

我試圖寫我自己的split功能像perlawk使用strtok_r功能在C它創建陣列,以及在數組元素的收益多少,我試過的東西,但我沒有正確理解動態內存分配的概念,請別人糾正我,也請注意。下使用strtok_r分割功能創建 - 如Perl和awk

我相信strdup照顧內存分配我是對嗎?

錯誤:段錯誤(核心轉儲)

這也是迄今爲止

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


int split(char * str, char **fields, const char *sep) 
{ 
    char *copy = strdup(str), *tmp, *word;  
    int count=0; 

    word = strtok_r(copy, sep, &tmp); 
    while(word) 
    { 
       word=strtok_r(NULL, sep, &tmp); 
     fields[count] = strdup(word); 
     count++;  
    } 

    return count; 
} 

int main() 
{ 
     char string[80]="a,b,c,d,e,f,g,h,i,j,k,l"; 
     const char *sep = ","; 
     char **cols; int i;   
    cols = malloc(strlen(string)+1*sizeof(char *)); 
    printf("%s\n",string); 
    int n = split(string,cols,sep); 
    printf("%s\t%d\n",string,n); 

    for(i=0; i<n; i++)printf("%s\t%s\n",string,cols[i]); 
    free(cols); 

    return 0; 
} 

感謝我試圖提前爲所有的志願者

+2

'cols'沒有被分配,它沒有指向任何有效的內存。解引用它是未定義的行爲。 – 2014-10-20 11:53:20

+0

@TheParamagneticCroissant:是否這'cols = malloc(strlen(string)+ 1 * sizeof(char *));'是正確的先生? – user3637224 2014-10-20 12:19:26

+0

@userXXX不,它不是。 – 2014-10-20 12:59:55

回答

1

你有不少初學者的錯誤:

1)分配內存cols,Eg在main()調用split()前:

cols=malloc(sizeof *cols * 256); 

調整數256,因爲你需要或計算它的基礎上的沒有。的「,」你在string

2)你的環部分是錯誤的,你是檢查NULL或存儲之前的令牌前再次令牌化

while(word) 
    { 
     word=strtok_r(NULL, sep, &tmp); 
     fields[count] = strdup(word); 
     count++;  
    } 

把令牌化在循環中的最後一條語句:

while(word) 
    { 
     fields[count] = strdup(word); 
     count++;  
     word=strtok_r(NULL, sep, &tmp); 
    } 

3)您還應該在返回之前在split()中免費獲得copy。否則,你的程序會有內存泄漏。請記住,strdup會爲您分配內存(並且您應該檢查它是否也返回NULL),但是您需要負責free

free(copy); 

這同樣適用於分配給cols[*]的內存。即打印字符串經過main(),做到:

for(i=0;i<n;i++) 
    free(cols[i]); 

雖然這不是絕對必要的,以釋放內存程序結​​束前右(因爲大多數現代操作系統無論如何都將取消分配它們),這是一個很好的做法,清理自己。

4)使用main()的標準原型,如:int main(int argc, char*argv[])int main(void)

+0

如果逗號的數量未知,該怎麼辦? – user3637224 2014-10-20 12:31:37

+0

你可以使用'strchr()'計數逗號(在一個循環中),並準確地分配你想要的指針數量。或者使用'realloc'(realloc,IMO,這裏有點矯枉過正,但是可能的方式)。 – 2014-10-20 12:33:46

+0

有時會出現多個分隔符,例如'cont char * sep =「,|: - <>」',有什麼想法? – user3637224 2014-10-20 12:36:45