假设我有一个指向以空结尾的字符串pString的指针.假设我想使用memcmp将其与另一个字符串进行比较,例如:

bool eq = memcmp(pString, "test", sizeof("test")) == 0;

pString可以依次位于虚拟页的末尾,并且下一页可以被取消分配.例如:

char c1 = pString[0]; // 'x'
char c2 = pString[1]; // '\0'
char c3 = pString[2]; // ACCESS VIOLATION

在这种情况下,如果memcmp不按顺序比较字节,程序可能会崩溃.我的问题是,能保证按顺序进行比较吗?

我知道有strcmp个.这个例子只是为了澄清这个问题.对于实际问题,请阅读标题.谢谢.

推荐答案

首先,这是一个错误的问题.memcmp可以以它想要的任何顺序比较字符,如果它在最后返回正确的答案.(例如,它可以将它们以8为一批进行比较,将字符串重新解释为long long,等等.)

正确的问题是,如果第一个不同的字节在该位置之前,是否允许向其传递比最后一个参数指定的字节更少的字节.

这会导致未定义的行为.

C++没有描述memcmp,而是引用C标准.其中写道(C23草案N3096,7.26.4.1"MemcMP函数"):

memcmp函数将s1指向的对象的前n个字符与s2指向的对象的前n个字符进行比较

您的对象没有"前n个字符",因为它总共有较少的字符,因此这是UB.

还有7.1.4"库函数的使用"/1,它说:

如果将函数参数描述为数组,则传递给该函数的指针应 具有这样一个值,即所有的地址计算和对对象的访问(如果 指针确实指向这种数组的第一个元素)是有效的.

虽然memcmp本身并不表示它接受数组,但有7.26.1"字符串函数约定"/1:

用于操作字符类型数组和被视为字符类型数组的其他对象.

所以我相信关于数组的引述也适用于memcmp.

C++相关问答推荐

为什么下面的C代码会进入无限循环?

exit(EXIT_FAILURE):Tcl C API类似功能

有没有更简单的方法从用户那里获取数据类型来计算结果

变量>;-1如何在C中准确求值?

当我运行/调试C程序时,Malloc()似乎正在将&q;r\r...&q;赋值给一个指针,我不确定为什么?

我无法让LLDB正确运行我的可执行文件

整型文字后缀在左移中的用途

Square不与Raylib一起移动

这个计算C中阶乘的函数正确吗?

C中的FREE函数正在触发断点

我的C函数起作用了,但我不确定为什么

如何在不使用字符串的情况下在c中编写函数atof().h>;

链表删除 node 错误

为什么Linux无法映射这个PT_LOAD ELF段?

如何读取程序中嵌入的数据S自己的ELF?

为什么我的半数组测试和奇数组测试不起作用?(我使用Assert进行调试)

表达式x&;&;(~x)应该返回1还是0?它依赖于编译器吗?

当我在34mb的.mp4文件中使用FREAD时,我得到了一个分段错误,我如何解决它?

当我将偏移量更改为任何非零值时,C中的mmap共享内存出现无效参数错误

尽管将其标记为易失性,但 gcc 是否优化了我的等待代码?