这是一个现有的代码,它查找与父路径相对应的相对路径。除了带有 GCC 4.7 的 SUSE 12 之外,它在其他平台上都按预期工作。 我在评论中提到了一个错误的输出和预期。 我试图理解为什么会发生这种情况? 这段代码有什么问题? 子字符串和父字符串均以 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;
}
最佳答案
来自 stpncpy
的手册页: 字符串不能重叠。
所以你应该使用memmove
,否则行为未定义。
stpncpy(start, child, PATH_MAX);
应该是
memmove(start, child, PATH_MAX > strlen(child) + 1? strlen(child) + 1: PATH_MAX);
您还应该记住,如果您在大型数组上使用小字符串,则 stpncpy
的效率非常低,因为它每次都会写入 n
个字符。在你的情况下,它会在你的字符串后面写入大约 4000 '\0'
。
手册页说
Exactly n characters are written at dest. If the length strlen(src) is smaller than n, the remaining characters in the array pointed to by dest are filled with null bytes ('\0')
关于c++ - stpncpy() 这里有问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33297735/