strtok()函数调用后崩溃程序被多次调用

时间:2014-01-29 21:13:50

标签: c 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 个答案:

答案 0 :(得分: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",它位于只读内存中,因此崩溃。如果您在mkdir中尝试通过库函数或其他方式修改pathname指向的数组中的任何,则会发生同样的崩溃。

最简单的治疗方法是写

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

main中,然后将 传递给mkdir;这会导致编译器从字符串文字到另一个可写字符数组生成一个副本。更复杂的方法是可能的,甚至是可取的,但我必须更多地了解你的更大目标是什么。