这是一个现有代码,它找到与父路径相对应的相对路径.它已经在平台上正常工作,除了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;
}
Run Code Online (Sandbox Code Playgroud)
来自Man Page 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
每次都会写字符.在你的情况下,它会'\0'
在你的字符串后写入大约4000 .
Man Page说
在dest处写入正好n个字符.如果长度strlen(src)小于n,则dest指向的数组中的剩余字符将填充空字节('\ 0')