【问题标题】:Checking if a pointer is in a malloc'd area?检查指针是否在 malloc'd 区域中?
【发布时间】:2017-01-02 16:29:18
【问题描述】:

我正在制作一个动态内存分配器,我需要检查当我释放它的一部分时,我传递给函数的指针实际上是否在该区域内。我有一个指向 malloc'd 区域开头的指针

typedef unsigned char byte;

static byte *memory // pointer to start of allocator memory

我在启动函数中分配的。我还存储了 malloc'd 区域的大小

static u_int33_t memory_size;   // number of bytes malloc'd in memory[]

如何确保 ptr 不是...(在伪代码中)

ptr < *memory || ptr > *memory + memory_size

并且该代码导致以下错误;

错误:不同指针类型的比较缺少强制转换 [-Werror] 如果(对象(内存+内存大小)) ^

我不确定我需要投射什么,不应该投射什么......

免费功能如下...

void memfree(void *object)
{
   if ( object < memory || object > (memory + memory_size)) {
  fprintf(stderr, "vlad_free: Attempt to free via invalid pointer\n");
  exit(EXIT_FAILURE);
   }
}

【问题讨论】:

  • 这似乎与以下内容重复:stackoverflow.com/questions/3065092/…
  • 那么,您的动态分配器有一个要分配的内存库,这一定是连续的? byte 的类型是什么? u_int33_t 的类型是什么?你提出的表达方式有什么问题?您的代码的可移植性如何?
  • @Jaime:我认为你提到的问题比这个问题中提出的问题更笼统。
  • 对不起,typedef unsigned char byte;便携性不是问题
  • 以后,请在问题中添加请求的信息——您可以编辑自己的问题。我已经为你添加了 byte 的 typedef。

标签: c pointers malloc


【解决方案1】:

原创

Raymond Chen's answer指出这是错误的

void memfree(void *_object)
{
   byte* object = (byte*)_object;
   if ( object >= memory && object < (memory + memory_size)) {
       /* defined guarantees - they happened to be in the same object. */
   } else {
      fprintf(stderr, "memfree: Attempt to free via invalid pointer\n");
      exit(EXIT_FAILURE);
   }
}

指针的类型需要相同。鉴于您似乎有一个字节范围,似乎最好使用字节。

来自 C 标准 n1570

当比较两个指针时,结果取决于指针中的相对位置 指向的对象的地址空间。如果两个指向对象类型的指针都指向 同一个对象,或者都指向同一个数组对象的最后一个元素,它们 比较相等。如果指向的对象是同一个聚合对象的成员, 指向稍后声明的结构成员的指针比较大于指向成员的指针 在结构的前面声明,以及指向具有较大下标的数组元素的指针 值比较大于指向具有较低下标值的同一数组的元素的指针。所有指向同一个联合对象成员的指针比较相等。如果 表达式 P 指向数组对象的元素,表达式 Q 指向 同一个数组对象的最后一个元素,指针表达式Q+1比较大于 P. 在所有其他情况下,行为是未定义的。

在这里,我认为未定义的行为是您无法判断在 2 个系统上是否会有一致的顺序,因此使用 a &lt; b 的代码在某些系统上可能为真,而在其他系统上可能为假。

新答案

使用

void memfree(void *_object)
{
   uintptr_t object = (uintptr_t)_object;
   if ( object >= (uintptr_t)memory && object < ((uintptr_t)memory + (uintptr_t)memory_size)) {
       /* defined guarantees - they happened to be in the same object. */
   } else {
      fprintf(stderr, "memfree: Attempt to free via invalid pointer\n");
      exit(EXIT_FAILURE);
   }
}

【讨论】:

  • 使用关系运算符比较不属于同一对象的指针是未定义的行为。
  • 您的编辑暗示好像行为在不同的架构上是一致的。它不是,结果不是假或真,它只是未定义。
  • 明白 - 你代表堆栈溢出的共识,但我不敢相信这是语言设计者的意思,事实上如果有可能有一个指针发生指向边界内,那么其他规则将是错误的(与不同类型的转换不会影响指针的值)。所以我相信我的解释是正确的
  • 标准的最后一行非常清楚:在所有其他情况下,行为是未定义的,如果指针不指向对象内存,就会发生这种情况, 被传递给 memfree。
猜你喜欢
  • 1970-01-01
  • 2012-06-10
  • 1970-01-01
  • 2011-06-07
  • 2020-03-29
  • 2013-02-05
  • 2014-06-17
  • 1970-01-01
相关资源
最近更新 更多