9

情况如下:

我们从使用 sprintf(如 strcat)的外部来源收到代码。像这样:

char buffer[1024];
sprintf(buffer, "Some text.");
sprintf(buffer, "%s%s", buffer, "Some more text");
sprintf(buffer, "%s%s", buffer, "again more text");

现在,这看起来很奇怪。我们都同意这看起来很奇怪。这不是我要问的。我们都知道应该使用strcat,而且更直接。我问的是这可能导致的潜在问题,除了看起来很奇怪之外。我们在 RHEL6 上运行,并使用 gcc 4.9.3。

谢谢你的帮助。

4

1 回答 1

11

该函数声明为

int sprintf(char * restrict s, const char * restrict format, ...);

注意类型限定符restrict

根据 C 标准(7.21.6.6 的 sprintf 函数)

2 sprintf 函数等价于 fprintf,除了输出写入数组(由参数 s 指定)而不是流。在所写字符的末尾写一个空字符;它不计为返回值的一部分。 如果复制发生在重叠的对象之间,则行为是 undefined

所以这些电话

sprintf(buffer, "%s%s", buffer, "Some more text");
sprintf(buffer, "%s%s", buffer, "again more text");

调用未定义的行为。

相反,调用可以写成

char buffer[1024];
int offset = 0;

offset = sprintf( buffer + offset, "Some text.");
offset += sprintf( buffer + offset, "%s",  "Some more text");
sprintf( buffer + offset, "%s",  "again more text");

或者

char buffer[1024];
char *p = buffer;

p += sprintf( p, "Some text.");
p += sprintf( p, "%s",  "Some more text");
sprintf( p, "%s",  "again more text");

至于限定词restrict,那么一般来说意味着(6.​​7.3 类型限定词)

8 通过限制限定指针访问的对象与该指针具有特殊关联。这种关联,在下面的 6.7.3.1 中定义,要求对该对象的所有访问直接或间接使用该特定指针的值

于 2021-10-21T16:01:25.640 回答