2014-01-29 67 views
0

我有一點麻煩弄清楚爲什麼的strtok()崩潰我的程序的strtok()函數之後崩潰程序調用它被稱爲不止一次

main() 
{ 
    NodePtr root, cwd; 
    char line[128] = {'\0'}; 
    char command[16] = {'\0'}; 
    char pathname[64] = {'\0'}; 
    char dirname[64] = {'\0'}; 
    char basename[64] = {'\0'}; 

    root = (NodePtr)malloc(sizeof(Node)); 

    gets(pathname); 

    strcpy(root->name, "/"); 
    root->nodeType = 'D'; 
    root->childPtr = NULL; 
    root->parentPtr = NULL; 
    root->siblingPtr = NULL; 

    mkdir(&root, pathname); 
    mkdir(&root, "/abc/fa"); 
} 

當我打電話的mkdir第一次,一切都按預期工作(更具體地說,使用strtok())。但是一旦mkdir第二次被調用,當mkdir被調用時,我的程序崩潰。

void mkdir(NodePtr *root, char pathname[64]) 
    { 
     char dirname[64] = {'\0'}; //only local variable for dirname 
     char basename[64] = {'\0'}; //only local variable for basename 
     int i = 0; 
     int j = 0; 
     int cut = 0; 
     int numOfDir = 0; //number of directories 
     int len = 0; //length of entered pathname 
     char* tok; //temp value to tokenize string and put it into dirPath 

     char** dirPath; //an array of strings that keeps the pathway needed to take to create the new directory 

     NodePtr newNode; 
     NodePtr currNode; 
     NodePtr currParentNode; 

     tok = "\0"; 

     ........ 

     printf("tok: %s\n", tok); 
     tok = strtok(pathname, "/"); //start first tokenized part 
     strcpy(dirPath[i], tok); //put first tokenized string into dirPathp[] 
    // printf("string: %s\n", dirPath[i]); 
     i++; 
     while(i < numOfDir) 
     { 
      tok = strtok(NULL, "/"); 
      strcpy(dirPath[i], tok); //put tokenized string into array dirPath[] 
    //  printf("string: %s\n", dirPath[i]); 
      i++; 
     } 
     .......... 

我的程序在

tok = strtok(pathname, "/"); 

具體打破第一次調用輸入沒有的strtok保持到的mkdir,這就是爲什麼它的崩潰?對於strtok來說很新穎,所以我很抱歉產生混淆。謝謝!

+1

您是否閱讀過[documentation](http://www.cplusplus.com/reference/cstring/strtok/)?它說*「在第一次調用時,函數需要一個C字符串作爲str的參數,[...]在隨後的調用中,該函數需要一個空指針」* – abelenky

回答

1

你沒有使用strtok本身就錯了,但你使用C字符串文字錯誤。

void mkdir(NodePtr *root, char pathname[64]) 

這個函數原型相當於void mkdir(NodePtr *root, char *pathname),應該這樣寫。我提到這一點是因爲重要的是要明白,你通過參考將字符串傳遞到mkdir

mkdir(&root, pathname); 
mkdir(&root, "/abc/fa"); 

在第一次通話中,pathname參數設置爲指向pathname變量main,這是在可寫的存儲器,所以一切正常。

在第二次調用時,pathname變量被設置爲指向字符串文字"/abc/fa",該文字位於只讀內存中,因此您會崩潰。如果您嘗試通過庫函數或其他方式修改pathname所指向的數組,中的任何mkdir都會導致同樣的崩潰。

最簡單的可固化是寫

char pathname2[64] = "/abc/fa"; 
main

,再通mkdir;這會導致編譯器從字符串文字生成一個副本到另一個可寫字符數組。更復雜的方法是可能的,甚至是可取的,但我必須更多地瞭解你的更大目標。

+0

感謝您的回覆!我明白我的問題是什麼。我能否將'pathname'設置爲NULL而不是創建第二個'pathname2'?我將不得不調用mkdir()未指定的次數,所以我希望我可以重複使用字符串路徑名 – Kosz

+0

您可以重複使用'pathname'緩衝區,當然可以通過複製其他字符串(使用'strncpy'或'memcpy'),而不是將其設置爲NULL。 – zwol

+0

N.B.其他你可能應該知道的事情是'strdup'和'PATH_MAX'。 – zwol

相關問題