使用strdup从字符串转换的c ++ char *与原始原始字符串不相等

时间:2014-10-30 15:43:10

标签: c equality cstring strdup

我想知道为什么将字符串转换为char *似乎使新char *不等于它来自的字符串。

如果我有:

//raw versions of the string:
string s = "fun";
char* c = "fun";

char* s_convert = strdup(s.c_str()); //converting the string to char*

printf("(string) == 'fun' -> %d\n", (s == "fun"));
printf("(char*) == 'fun' -> %d\n", (c == "fun"));
printf("(char* convert) == 'fun' -> %d\n", (s_convert == "fun"));

printf("(string) == (char*) -> %d\n", (s == c)); //does new char* equal original string

产生

(string) == 'fun' -> 1 //true
(char*) == 'fun' -> 1  //true
(char* convert) == 'fun' -> 0 //false
(string) == (char* convert) -> 1 //true

因此转换后的char *仍然等于它来自的原始字符串。但由于某些原因,char* s_convert不等于它来自的文字字符串,尽管原始的string s确实如此。

为什么会这样?还有一种更好的方法可以将字符串转换为char *而不会导致这种情况吗?

6 个答案:

答案 0 :(得分:5)

对于指针,==比较指针值;它无法知道指针应该指向C风格的字符串(而不是单个字符或未终止的数组),并且不会查看它指向的任何内容。 strdup返回的指针不是任何字符串文字的地址,因为该函数的目的是为字符串的新副本分配内存。

如果由于某种原因你真的必须使用C风格的字符串,你可以将它们与strcmp进行比较。但C ++字符串更方便;使用它们,除非有充分的理由不这样做。

答案 1 :(得分:1)

始终使用strcmp来比较char *&#39>。

答案 2 :(得分:1)

strdup复制字符串并返回指向内存中分配的新字符串的指针。此指针的地址与原始字符串的地址不同,因此您可以使用strcmp()比较两者,但由于这些字符串所处的内存位置不同,比较指针将失败。

答案 3 :(得分:1)

让我们逐一进行比较:

printf("(string) == 'fun' -> %d\n", (s == "fun"));

std::string变量与字符串文字进行比较。按预期工作(即真正检查s是否包含字符串“fun”),因为std::string为此目的而重载operator==

printf("(char*) == 'fun' -> %d\n", (c == "fun"));

c中存储的地址与字符串文字“fun”的地址进行比较。结果可能是真或假。在你的情况下,这是真的,因为编译器优化了你的代码:它看到你多次使用“fun”,并且只将字符串文字一次存储在内存中,所以地址总是相同的。例如,如果c在不同的翻译单元中被分配了文字“fun”,则结果将是错误的。

printf("(char* convert) == 'fun' -> %d\n", (s_convert == "fun"));

s_convert中存储的地址与字符串文字“fun”的地址进行比较。如上所述,字符串文字“fun”具有编译器选择的特定地址。它不会与明确复制的字符串进行比较(它与std::string变量无关)。 strdup创建新分配的内存,因此地址不会与之前存在的任何内容相等。

printf("(string) == (char*) -> %d\n", (s == c)); //does new char* equal original string

再次,将std::string与C风格的字符串进行比较。这实际上比较了字符串,并检查s是否包含存储在地址c的以空字符结尾的字符串,这要归功于operator== std::string的重载,因此结果为真。

总结:您观察到的效果与std::string和以null结尾的C风格字符串之间的转换无关或几乎没有关系。你只是不比较你认为你比较的东西。如果您想比较以空值终止的“原始”字符串,请使用strcmp,或者在将==与其他内容进行比较时使用std::string,并且您会打赌您期望的结果。

答案 4 :(得分:0)

当你在指针上使用相等运算符时,除非存在重载,否则它将比较指针。因此,当您执行s_convert == "fun"时,将指针 s_convert与指向字符串文字"fun"的指针进行比较。

它适用于c == "fun"的原因是因为c已经指向该字符串文字。

答案 5 :(得分:0)

你应该使用

0 == strcmp( c, "fun" );

而不是

c == "fun";