我正在从事其他项目,对我来说,发现 strdup 的奇怪行为。
假设我们有 3 个简单文件:
foo.h:
#ifndef FOO_H
#define FOO_H
void example(char *a);
#endif //FOO_H
foo.c:
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
void example(char *a) {
if (a == NULL) {
fprintf(stderr, "a is NULL");
exit(1);
}
char *temp = strdup(a);
printf("%s", temp);
}
bar.c
#include <stdio.h>
#include <stdlib.h>
#include "foo.h"
int main() {
char *a = "Hello World\n";
example(a);
return 0;
}
当我编译这些时,我收到警告,当我运行这些时,我收到段错误:
foo.c:10:18: warning: implicit declaration of function ‘strdup’ [-Wimplicit-function-declaration]
foo.c:10:18: warning: initialization of ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
解决方案是不使用 c11 编译或将自己的 strdup 声明放在 .h 文件中。
所以问题是,为什么会发生这种情况。
解决方案是不使用 c11 编译或将自己的 strdup 声明放在 .h 文件中。
不,解决方案是为
string.h
添加 strdup()
。请注意,strdup()
直到 C2X 才标准化,并且您需要这些功能测试宏(除非您在使用 GCC 或 Clang 编译时指定 std=c2x
),按照 strdup()
的手册页:
glibc 的功能测试宏要求(请参阅 feature_test_macros(7)):
strdup():
_XOPEN_SOURCE >= 500
|| /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
|| /* glibc <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE
有关错误消息,请参阅:C 中的隐式函数声明和C89、C90 或 C99 中的所有函数都需要原型吗?以及C++ 和 C 中的标头保护。
另请注意,
strdup()
与需要释放的malloc()
一起动态分配内存。您的代码中缺少对 free()
的调用。
此外,如果分配内存失败,它会返回一个空指针,在这种情况下,
temp
将保存一个空指针,并且随后对printf()
的调用将调用未定义的行为。