这是检查内存中2个c字符串是否重叠的正确且可移植的方法吗?

inf*_*ler 44 c

可能不是最有效的方式,但它是否正确且便携?

int are_overlapping(const char *a, const char *b) {
  return (a + strlen(a) == b + strlen(b));
}
Run Code Online (Sandbox Code Playgroud)

澄清:我正在寻找的是内存重叠,而不是实际内容.例如:

const char a[] = "string";
const char b[] = "another string";
are_overlapping(a, b); // should return 0
are_overlapping(a, a + 3); // should return 1
Run Code Online (Sandbox Code Playgroud)

Car*_*rum 33

是的,您的代码是正确的.如果两个字符串在样本位置结束,则它们按定义重叠 - 它们共享相同的空终止符.两个字符串都相同,或者一个是另一个字符串的子字符串.

关于你的程序的一切都是完全定义良好的行为,所以假设符合标准的编译器,它应该是完全可移植的.

标准中的相关位来自6.5.9 Equality运算符(强调我的):

两个指针比较相等,当且仅当两个都是空指针时,两者都是指向同一对象的指针(包括指向对象的指针和开头的子对象)或函数,两者都是指向同一数组的最后一个元素的指针对象,或者一个指向一个数组对象末尾的指针,另一个是指向紧跟在地址空间中第一个数组对象之后的另一个数组对象的开头的指针.

  • 忘了这一点,我完全忽略了字符串是空终止的. (4认同)
  • 如果它解释为什么支持`==`,即使不知道`a`和`b`是指向同一个对象(或超出它的一个字节)的指针,这个答案会更有用. (4认同)
  • NP,我想很多人都是在这个问题上做到的. (3认同)
  • 不,这根本不重要.试试一些例子. (2认同)
  • @EricPostpischil - 完成了,但你有很多代表自己添加它.请放心吧 - 我相信你!=) (2认同)

Sco*_*ica 12

考虑到zdan对我之前的帖子(可能很快就会被删除)的评论,我得出的结论是检查端点就足够了.

如果存在任何重叠,则空终止符将使两个字符串不同.让我们看看一些可能性.

如果你开始

a 0x10000000 "Hello" and somehow add
b 0x10000004 "World",
Run Code Online (Sandbox Code Playgroud)

你会有一个单词:HellWorld,因为W会覆盖\ 0.它们将在同一端点结束.

如果你以某种方式写到同一个起点:

a 0x10000000 "Hello" and
b 0x10000000 "Jupiter"
Run Code Online (Sandbox Code Playgroud)

你将拥有Jupiter这个词,并拥有相同的端点.

是否存在可以具有相同端点但没有重叠的情况?的种类.

a = 0x1000000 "Four" and
b = 0x1000004 "".
Run Code Online (Sandbox Code Playgroud)

这也会产生重叠.

我想不出任何时候你会有重叠的地方你没有匹配的端点 - 假设你正在将空终止字符串写入内存.

简而言之:是的,您的支票就足够了.

  • @ ErnestFriedman-Hill那包括我.我实际上有3个upvotes说"不,你必须检查整个字符串"(和2 downvotes.:-)) (3认同)