我知道,像这样的事情
char a[1024] = "Hello";
char b[6] = "World";
sprintf(a, "%s %s", a, b);
导致未定义的行为。我知道,我可以使用其他函数,例如
strcat
,但是如果我想使用sprintf
函数(我知道我可能会写遍数组边界的风险),那么我可以删除未定义的行为(如果我写这样的东西)sprintf(a + strlen(a), "%s %s", a, b)
还是仍然不确定,我必须使用一个临时变量?
最佳答案
你说得对sprintf(a, "%s %s", a, b);
将导致undefined behavior,因为源字符串和目标字符串重叠。
但是,线sprintf(a + strlen(a), "%s %s", a, b);
仍然会导致未定义的行为,因为a + strlen(a)
是字符串a
的终止空字符的地址(这意味着源字符串a
和目标字符串a + strlen(a)
仍然重叠)。如果字符串不应重叠,则必须将行更改为以下内容:sprintf(a + strlen(a) + 1, "%s %s", a, b);
由于不再有任何重叠,因此该行不会导致未定义的行为。
如果您希望能够将内存从一个内存缓冲区复制到另一个内存缓冲区,该内存缓冲区与第一个内存缓冲区重叠,那么建议您使用函数 memmove
。与 memcpy
相比,函数memmove
允许重叠的内存缓冲区,其行为就像在将内容写入目标缓冲区之前先将其写入临时缓冲区一样。因此,即使缓冲区重叠,该函数的行为也不是未定义的,而是定义良好的。不幸的是,字符串没有等效的函数strmove
。
关于c++ - C++ sprintf删除未定义的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60589006/