将char指针复制到char指针数组时会发生Seg错误

时间:2017-04-07 08:32:41

标签: c pointers strcpy

我正在读取文件中的一行文本,并尝试将其拆分为strtok()的空格,然后使用strcpy()将每个标记存储在一个char指针数组中,在一个名为tokenize

代码:

/**
** Tokenizes contents of buffer into words
** Delimiter is a space character
*/
void tokenize(char *buffer, char *tokens[]){
    char *token = NULL;
    int i = 0;
    token = strtok(buffer, " ");
    while(token != NULL){
        strcpy(tokens[i], token);//seg fault line
        token = strtok(NULL, " ");
        i++;
    }
}

我假设,基于K& R中的函数描述,我的调用将起作用,因为我传递了一个char指针,这是tokens[i]应该取消引用的,以及另一个包含内存地址的char指针要复制的字符串,这是token应该是什么。但是,当我尝试strcpy时,我遇到了一个段错误。

在使用对main的调用检索到一行后,立即在fgets()中调用此函数。 buffer被声明为char buffer[MAXLINE_LEN - 1],其大小为100. tokens被声明为char *tokens[MAXLINE_LEN - 1]

致电tokenize中的main

while(fgets(buffer, MAXLINE_LEN, inputFile)){
    int choice;
    printf("%s", buffer);
    tokenize(buffer, tokens);
    /**
    ....
    */
}

我正在使用:gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

修改 声明tokens(这发生在上面显示的while循环之前和main中):

char *tokens[MAXLINE_LEN - 1];//MAXLINE_LEN - 1 = 100

int a;
for(a = 0; a < MAXLINE_LEN - 1; a++)
    tokens[a] = NULL;

2 个答案:

答案 0 :(得分:0)

我能想到的四种可能性

  1. tokensNULL或未初始化
  2. tokens已初始化,但您尚未分配足够的空间。如果为四个令牌分配空间但strtok()解析五个令牌会怎样?
  3. tokens的个别元素是n NULL或未初始化
  4. 您没有在每个elemant中分配足够的空间来复制令牌字符串。
  5. 其中一个或多个几乎肯定适用于您的代码。修复它的一种方法是在函数内部完全分配tokens并将其返回指针(将计数作为返回值)。

    enum
    {
        CHUNK_SIZE = 16; // A trick to get an int constant in C that works everywhere a #define works
    };
    
    size_t tokenize(char *buffer, char **tokenRet[])
    {
        size_t capacity = 0;
        char** tokens = NULL;
        size_t count = 0;
        char *token = NULL;
        token = strtok(buffer, " ");
        while(token != NULL)
        {
            count++;
            if (count > capacity)
            {
                capacity += CHUNK_SIZE;
                tokens = realloc(tokens, capacity * sizeof *tokens);
            }
            tokens[count - 1] = strdup(token);//strdup mallocs space and copies the string into it
            token = strtok(NULL, " ");
        }
        *tokenRet = tokens;
        return count;
    }
    

    像这样称呼

    char** myTokens = NULL;
    size_t tokenCount = tokenize(buffer, &myTokens);
    

    然后在最后整理,free() tokenCount的第一个myTokens元素,然后免费myTokens

答案 1 :(得分:-1)

&#34; char *令牌[]&#34;的大小是多少? 你可能在&#34; char * buffer&#34;中有更多的令牌。比令牌[]可以容纳。 另外,你是否为指针数组分配了内存?