c - 缓冲区上的基名进入段错误

标签 c pointers strcmp

我现在正在使用 basename 进行调整,我遇到了一个非常奇怪的情况(至少对我而言)。这是代码:

char buffer[300];
char* p;

strcpy(buffer, "../src/test/resources/constraints_0020_000");
printf("%d\n", strcmp(basename("../src/test/resources/constraints_0020_000"), "constraints_0020_000")); //works as expected
printf("assert testBasename02");
printf("%d\n", strcmp(basename(buffer), "constraints_0020_000") == 0);
printf("done 1\n"); //goes in segmentation fault
printf("%d\n", strcmp(basename(&buffer), "constraints_0020_000") == 0);
printf("done 2\n"); //goes in segmentation fault
printf("%d\n", strcmp(basename(&buffer[0]), "constraints_0020_000") == 0);
printf("done 3\n"); //goes in segmentation fault
p = malloc(strlen("../src/test/resources/constraints_0020_000") +1);
strcpy(p, "../src/test/resources/constraints_0020_000");
printf("%d\n", strcmp(basename(p), "constraints_0020_000") == 0); //works as expected
free(p);
printf("all done\n");

第一个 strcmp 完全正常工作;令我困惑的是第二个:为什么缓冲区会出现段错误?我尝试以不同的方式对缓冲区进行编码,但结果是一样的。

我当然可以忍受这种行为,但是......我真的不明白如果我给他一个 const char* 或者 basename 有什么区别一个缓冲区(最后也是一个 char*)。

是否有解释此行为的文档?只有我吗?我试图寻找解释,但找不到任何解释。

这里是我的电脑规范(如果你需要的话):

  • 操作系统:Ubuntu 16.4(64 位在 Windows 10 64 位上虚拟化);
  • CPU(不是我认为有用的):Intel® Core™ i5-3230M CPU @ 2.60GHz × 2;

最佳答案

根据man page ,

Bugs

In the glibc implementation of the POSIX versions of these functions they modify their argument, and segfault when called with a static string like "/usr/". [...]

基本上,

 basename("../src/test/resources/constraints_0020_000")

调用调用 undefined behavior因为这是试图修改字符串文字。


注意:如手册页中所述,需要更改单词。读起来像,

In the glibc implementation of the POSIX versions of these functions they modify their argument, and invokes undefined behavior when called with a static string like "/usr/". [...]

段错误是 UB 的副作用之一,但不是唯一的副作用。

FWIW,尝试修改字符串文字本身会调用 UB。引用 C11,第 6.4.5 章,字符串文字

[...] If the program attempts to modify such an array, the behavior is undefined.


编辑:

正如后续评论中所讨论的,另一个问题是缺少头文件。你需要有

  #include <libgen.h>

添加是为了使函数 basename() 的前向声明可用。

关于c - 缓冲区上的基名进入段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41367050/

相关文章:

c - C 中的 void* 怪异

c - 尝试用C语言编写单词搜索程序

C 代码 - 为什么输出在我的代码中返回意外值?

c - 效率 : char array vs int array

c - C中使用队列进行二叉树级顺序遍历

c++ - 为什么我的指针变量持有其他地址,但仍成功指向变量?

Java对象引用问题

c - 如何正确比较 C 中的字符串?

c - 使用 strcmp() 插入函数

c - libjit 是否动态地将一段代码转换为可执行文件?