为什么我们需要strdup()?
当我在完成一项任务时,我发现我们不应该使用如下任务:
char *s="HELLO WORLD";
使用这种语法的程序容易崩溃。
我尝试过并使用过:
int fun(char *temp) { // do sum operation on temp // print temp. } fun("HELLO WORLD");
甚至上面的工作(虽然输出是编译器和标准特定的)。
相反,我们应该尝试strdup()或使用const char *
我曾尝试在博客上阅读其他类似的问题,但无法得到上述代码为何应该工作的概念。
内存分配? const有什么不同?
让我们澄清一下事情。 你从来没有特别需要strdup
。 它只是一个在堆上分配char*
的副本的函数。 它可以通过许多不同的方式完成,包括基于堆栈的缓冲区。 你需要的是结果,一个char*
的可变副本。
你列出的代码很危险的原因是它将字符串文字中的一个真正的常量字符串传递给一个需要一个可变字符串的插槽。 遗憾的是,在C标准中允许这样做,但这本身就很危险。 写入常量字符串将产生意外结果并经常崩溃。 strdup
函数修复了这个问题,因为它创建了一个可变副本,该副本放在一个期望可变字符串的插槽中。
字符串文字存储在程序的数据段中。 操纵他们的指针将修改字符串文字,这可能导致……奇怪的结果。 使用strdup()
将它们复制到堆或堆栈分配的空间。
字符串文字可以存储在没有写权限的内存部分中。 尝试写入它们将导致未定义的行为。 const意味着编译器确保不写入指针,从而保证不以这种方式调用未定义的行为。
这是C中的一个问题。虽然字符串文字是char *
你不能修改它们,因此它们实际上是const char*
。
如果您使用的是gcc
,则可以使用-Wwrite-strings
来检查是否正确使用了字符串文字。
阅读我的答案(数组和字符串)Java和C之间的区别 。 它包含有关字符串的部分中您的问题的答案。
您需要了解静态和内存分配之间存在差异,并且您不会求助于相同的内存空间。