2009-08-04 80 views
3

我有一个函数,它以char *作为唯一的参数。然后我执行一些strtok操作。有时候它有效,有时候它会发挥作用。它的工作取决于字符串是如何构建的。比如这里有两种情况。c字符串分配的区别?

int main() 
{ 
    char glob[] = "/abc/def/ghi"; 
    char *glob2 = "/abc/def/ghi"; 

    func(glob); //this one works 
    func(glob2); //this one doesnt work 

    return 0; 
} 

这两种分配方法之间的区别是什么,为什么strtok为第二个分配方法炸掉?

+9

阅读litb的char *和char *之间区别的优秀帖子 - http://stackoverflow.com/questions/308279/c-strings-vs/308724#308724 – Falaina 2009-08-04 14:11:18

+3

将字符串常量赋给char *(取而代之的const char *)只是由于历史原因才合法。它被认为已被弃用,一些编译器会向你发出警告。 – 2009-08-04 14:13:22

回答

12

strtok()基本上修改输入字符串。

char *glob2 = "/abc/def/ghi"; 

在上述情况下,glob2指向只读数据并且因此发生故障,而与“char glob[] = "/abc/def/ghi";”的数据不是只读的,它在字符数组可用。因此它允许修改。

+0

从手册页引用: 使用这些函数时要小心。如果你确实使用它们,请注意: - 这些函数修改它们的第一个参数。 - 这些函数不能用于常量字符串。 - 分隔符的标识丢失。 - strtok()函数在解析时使用了一个静态缓冲区,所以它不是线程安全的。如果这对你很重要,请使用strtok_r()。 – 2009-08-04 14:14:10

6

Strtok写入分配给字符串的内存。

在大多数编译器/运行时/硬件上,您无法写入静态分配的字符串内存。你可以写入堆栈。

7

char [] str1 =“foo”在栈上分配一个字符数组(假设这是一个函数)。该数组可以被修改而没有问题。

const char * str =“foo”给你一个指向字符串foo的指针,它通常驻留在只读存储器中。

char * str =“foo”将执行相同的操作,但隐式删除const(实际上并未改变指针指向只读内存的事实)。

-2

其他评论是正确的;你应该使用strtok_r()来代替。