【问题标题】:unexpected result in C strcpy and strncpy combinationC strcpy 和 strncpy 组合的意外结果
【发布时间】:2018-06-04 23:29:29
【问题描述】:

在我高中期末考试的练习中,我们得到了以下问题:

在代码执行后查找字符串 s1、s2 和 s3 的值:

char s1[] = "Short Message Service", *s2, *s3;
s2 = strchr(s1, 'M');
s3 = strrchr(s2,'S');
strncpy(s1 + 1, s2, 1);
strcpy(s1 + 2, s3);

全班预期结果为:

s1 = SMService
s2 = Message Service
s3 = Service

当我们通过执行代码对其进行测试时,我们惊讶地看到结果是:

s1 = SMService
s2 = ice
s3 = Service

问题是没有人能弄清楚为什么 s2 被缩短了。在试图弄清楚时,我发现 s2 一直保留着“消息服务”,直到执行“strcpy”函数的最后一行代码。我认为问题可能出在指针地址中,但我无法弄清楚 strcpy 是如何影响 s2 的。

所以我的问题是为什么 s2 不是我们预期的那样,为什么它被缩短了?

【问题讨论】:

  • 似乎被缩短了,因为终止与最后的 strcpy 一起被删除。这所有都发生在同一个缓冲区s1[])中,而调试器会让这一点显而易见。看看s2 指向的位置:s1+6。现在看看最后的strcpy 后面的s1+6 是什么:SMService 的尾部字符,那是ice 和一个终止符。
  • @WhozCraig 谢谢你的解释。但如果是这样的话(s2 指向:s1+6s3 指向 s2+7 还是直接指向 s1+13?在这两种情况下,s3 最终如何等于"Service"
  • s3 中存储的地址在分配strrchr 结果后永远不会改变,即s1+14 没有任何东西通过缓冲区末尾覆盖或更改该地址处的数据,因此s3 的渲染在渲染时显示为简单的 Service
  • @WhozCraig 谢谢你,你的解释真的很有帮助!

标签: c pointers strcpy string.h


【解决方案1】:

在您的代码中s2 指向s1 中的M,然后在您的最后一个strcpy 中被s3 覆盖:

char s1[] = "Short Message Service", *s2, *s3;
s2 = strchr(s1, 'M');   // s2 is pointing to s1 + 6 = Message Service
s3 = strrchr(s2, 'S');  // s3 is pointing to s1 + 14 = Service 
strncpy(s1 + 1, s2, 1); // Write M in to s1[1], s1 = SMort Message Service 
strcpy(s1 + 2, s3);     // Write Service into s1 + 2
                        // s1 = SMService but s2 is pointing to s1 + 6 = ice

【讨论】:

  • strcpy(s1 + 2, s3); 是 UB 作为源和目标重叠。违反char *strcpy(char * restrict s1, const char * restrict s2);restrict。这会使测试用例失败。
  • @chux:我不相信这是真的。 s3 的值为 s1+14strcpy 会将 8 个字符(包括终止 NUL)复制到位置 s1+2s1+9。没有重叠。通过strcpy 参数s2 访问的对象不会被s1 参数修改(甚至读取)。 restrict 施加的限制适用于指针引用的对象;对于char* 类型的指针,所有这些对象都具有char 类型。换句话说,restrict 不关心指针所引用的值的某种程度;仅限于实际值。
  • 参见 6.7.3.1 第 8 和 9 段中的示例。对f(50, d + 50, d) 的调用正是有效的,因为该调用中两个指针参数引用的范围不重叠。第二次调用f(50, d + 1, d),有重叠,调用的是UB。
  • @rici 同意——对我来说已经晚了。靠近边缘不超过边缘。
猜你喜欢
  • 1970-01-01
  • 2014-03-27
  • 2013-11-27
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 2020-07-01
  • 1970-01-01
相关资源
最近更新 更多