在我的程序中,我使用basename函数来获取分区。 首先,我写一个这样的句子:
if (!strncmp(buf,
basename("/dev/mmcblk0p3"),
strlen(basename("/dev/mmcblk0p3"))) {
ret = 1;
} else {
ret = 0;
}
buf指向字符串“mmcblk0p3”,但是ret = 0,使用gdb,我发现basename(“/ dev / mmcblk0p3”)返回了一个奇怪的字符串,但是当我改变程序时这样:
char *p = NULL;
p = basename("/dev/mmcblk0p3");
if (!strncmp(buf, p, strlen(p)) {
ret = 1;
} else {
ret = 0;
}
ret为1,程序运行正常。有什么不同? basename不能这样使用? 编译环境是armel7v / gcc。
答案 0 :(得分:3)
经典(POSIX)basename()
函数可以修改其输入字符串。
似乎您的版本正在修改输入,因此第二次调用没有获得与第一次相同的字符串,使上述代码非常混乱。
更糟糕的是:您还通过basename()
修改字符串文字来调用未定义的行为。
答案 1 :(得分:1)
使用返回字符串的非重入函数basename的一个后果是后续调用使先前结果无效。您需要在进行第二次调用之前复制返回值,或者在第二次调用返回后停止使用旧值。这是因为basename只有一个内部缓冲区来存储其结果,假设它没有修改它的参数(看起来就是你的程序的情况,因为它不会在字符串文字上崩溃;但是,它是未定义的行为)。
按如下方式修改程序以使其可移植:
char *p = NULL;
char pathname[] = "/dev/mmcblk0p3";
p = basename(pathname);
if (!strncmp(buf, p, strlen(p)) {
ret = 1;
} else {
ret = 0;
}