这是一个现有代码,它找到与父路径相对应的相对路径。它已经在平台上正常工作,除了SUSE 12和GCC 4.7。 我在评论中提到了错误输出之一。 我想了解为什么会发生这种情况? 此代码有什么问题? 子字符串和父字符串都以NUL字符结尾。我看到的唯一另一件事是源和目标从同一个内存位置传递,换句话说我们正在尝试更新相同内存位置的值。 这是真正的问题吗?
//child = /dev/shm/4/tmp/backup/datadir/performance_schema/events_stages_summary_by_account_by_event_name.frm
//parent = /dev/shm/4/tmp/backup
char* get_relative_path(char *child, const char *parent)
{
char* start= child;
static char dot[] = "." ;
....
....
/* Check if child = parent + "/" + .... */
if (strstr(child, parent) == child)
{
int parent_len= strlen(parent);
/* parent path may or may not have the "/" suffix. check for both. */
if (parent[parent_len-1] == FN_LIBCHAR ||
child[parent_len] == FN_LIBCHAR)
{
child+= parent_len;
while (*child && *child == FN_LIBCHAR)
child++;
if (*child == 0)
return dot;
}
}
// At this point the value of
// start = /dev/shm/4/tmp/backup/datadir/performance_schema/events_stages_summary_by_account_by_event_name.frm
// child = datadir/performance_schema/events_stages_summary_by_account_by_event_name.frm
if(start != child)
{
stpncpy(start, child, PATH_MAX);
}
// At this point expected value of start = datadir/performance_schema/events_stages_summary_by_account_by_event_name.frm
// But actual value of start = datadir/performance_schenamevents_stages_summary_by_account_by_event_name.frm
return start;
}
答案 0 :(得分:5)
来自stpncpy
的手册页:The strings may not overlap.
所以你应该使用memmove
,否则行为是未定义的。
stpncpy(start, child, PATH_MAX);
应该是
memmove(start, child, PATH_MAX > strlen(child) + 1? strlen(child) + 1: PATH_MAX);
您还应该记住,如果在大型数组上使用小字符串,stpncpy
效率非常低,因为每次都会写n
个字符。在你的情况下,它会在你的字符串后写出大约4000 '\0'
Man Page说
在dest上写入了n个字符。 如果长度strlen(src)小于n,则为剩余字符 在dest指向的数组中填充空字节('\ 0')