c++ - C++ sprintf删除未定义的行为

标签 c++ printf valgrind

我知道,像这样的事情

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/

相关文章:

c++ - 将记录数组的元素传递给临时记录数组的问题

c++ - char 数组存储太多字符? (c++)

c - printf 打印到 c 中的二进制文件

c - 没有 valgrind 的内存泄漏搜索

C++ if语句不返回

c++ - gcc 中的哪些 -W 值对应于哪些实际警告?

c++ - 返回交点和对象相交

c - scanf 输入的 %d 间距

c - Valgrind 内存泄漏报告中的时间戳不正确

c++ - Valgrind 中的无效写入和读取操作