【发布时间】:2017-01-02 18:58:54
【问题描述】:
我有一段我正在“守护”的记忆,由
定义typedef unsigned char byte;
byte * guardArea;
size_t guardSize;
byte * guardArea = getGuardArea();
size_t guardSize = getGuardSize();
为此,可接受的实现是:
size_t glGuardSize = 1024; /* protect an area of 1kb */
byte * getGuardArea()
{
return malloc( glGuardSize );
}
size_t getGuardSize()
{
return glGuardSize;
}
下面的 sn-p 可以为任何指针(来自不同的 malloc、来自堆栈等)返回 true 吗?
if ( ptr >= guardArea && ptr < (guardArea + guardSize)) {
return true;
}
标准规定:
区域内的值将返回 true。 (当 ptr 是成员时,所有行为都正确。)
指针将是不同的(a == b 仅当它们相同时)。
- 字节数组中的所有地址都可以通过递增基数来访问。
- 任何指针都可以与 char * 相互转换,而不会造成损坏。
所以我无法理解来自不同对象的任何指针的结果如何为真(因为它会破坏该区域内指针之一的不同规则)。
编辑:
用例是什么?
检测指针是否在区域内的能力非常重要,有时会编写代码
if ( isInMyAreaOfInterest( unknownPointer ) ) {
doMySpecialThing( unknownPointer );
} else {
doSomethingElse( unknownPointer );
}
我认为语言需要通过使此类结构简单明了来支持开发人员,而我们对标准的解释是开发人员需要强制转换为 int。由于不同对象的指针比较的“未定义行为”。
我希望能弄清楚为什么我不能做我想做的事(我的 sn-p),因为我发现的所有关于 SO 的帖子都说该标准声称未定义的行为,没有任何解释或示例为什么这个标准比我想要的更好。
目前,我们有一条规则,我们既不理解为什么存在这条规则,也不怀疑这条规则是否对我们有帮助
示例帖子:
【问题讨论】:
-
其实依赖于
getGuardArea()和getGuardSize();的实现。只要你不详细说明,这个问题是无法回答的。 -
只是为了好奇,用例是什么?
-
我仍然不明白你的问题。如果您使用
malloc获得一些内存,则可以确定不会再次分配该内存块(除非您系统上的malloc严重损坏)。从概念上讲,您的 sn-p 有效。有什么问题?指针的铸造?你能链接到这些讨论 UB 的帖子吗? -
所以我无法理解来自不同对象的任何指针的结果如何为真。问题的前提是错误的。如果使用关系运算符比较指向不同对象的两个指针,则会导致未定义的行为。结果不是假或真,而是允许发生任何事情,因为它是未定义的行为,在这里解释:stackoverflow.com/a/4105123/4082723
-
@Lundin:由非迟钝的程序员为现代线性地址机器编写的编译器不应该将关系运算符解释为在所有数据指针之间定义一致的非重叠排序,这是没有现实原因的。不幸的是,几十年来一直被正确识别为迟钝的编译器行为今天被认为是时尚的。
标签: c pointers language-lawyer