检查指针是否指向有效结构

时间:2017-07-07 09:36:15

标签: c pointers struct

我有N个静态分配的结构。

struct exemple{
     ...
}

struct exemple array[N];
struct exemple *test_ptr = 0x3; /* random address */

我可以检查test_prt是否指向有效地址吗?即它指向一个“结构示例”分配。

5 个答案:

答案 0 :(得分:5)

你不能。你必须知道。如果正确管理指针,这不是问题。一旦你销毁它们指向的对象,一个好习惯就是始终设置指向0 / NULL的指针。然后,您只需使用if (ptr)if (!ptr)(或更详细:if (ptr == NULL) / if (ptr != NULL))进行测试。

请注意您的上次作业

struct exemple *test_ptr = 0x3; /* random address */

无效。你不能为指针分配一个整数。但你可以转换为指针类型;

struct exemple *test_ptr = (struct exemple *)0x3; /* random address */

结果取决于您的实施/系统。

答案 1 :(得分:2)

您只能通过执行pointer != NULL来检查指针是否有效,因为有效指针会处理除“NULL”以外的任何内容。

在您的情况下,要检查您的指针是否指向任何数组条目,您只能这样做:

size_t i = 0;
int isValid = 0;
for (i = 0; i < N; i++) {
    if (test_ptr == &array[i]) {
        isValid = 1;
        break;
    }
}

if (isValid) {
    //Pointer points to one of your array entry
}

但总的来说,你不能只测试指针是否指向特定的有效位置。由你来照顾它指向的地方。它也可以具有 NON-NULL 值但指向无效位置,例如:

int* ptr = malloc(10); //Now points to allocated memory
*ptr = 10;
free(ptr);  //Free memory
*ptr = 10;  //Undefined behaviour, it still points to the same address but
            //we don't know what will happen. Depends on implementation

答案 2 :(得分:1)

通常,不,你不能测试指针是否有效。

但是,如果您想知道指针是否指向数组的元素,您可以:

if(test_ptr >= &array[0] && test_ptr < &array[N]
        && ((intptr_t)test_ptr - (intptr_t)array)%((intptr_t)(&array[1]) - (intptr_t)array) == 0) {
    // test_ptr points to an element of array
}

这是有效的,因为数组是连续分配的。

答案 3 :(得分:0)

没有语言方法,但在某些情况下,您可以尝试在结构的某些点处具有一些已知值。如果指向的内存位置具有这些值,您可以将其视为有效 - 但当然您没有任何保证。但是你需要在创建结构时编写自己的函数,并在销毁它时(通过在释放内存之前填充零)。这是一个非常周的解决方法 - 但如果你连接另一个措施并接受开销,就会使程序行为错误的可能性降低。

有时它被称为安全cookie。

当然可以使其更复杂 - 在某些位置,您只能抵消这些Cookie。它使得内存中的随机位置不太可能具有这样的数据链:)

答案 4 :(得分:0)

我不知道我是否正确地提出了你的问题。

如果你想知道指针是否指向某种类型的结构(例如,将我的结构转换为void *,反之亦然),我会采取下一种方式:

#include <assert.h>
struct my_struct {
#ifndef NDEBUG
#define MY_STRUCT_MAGIC 0x1234abcd
  uint64_t magic;
#endif
  int my_data;
};

void init_struct(struct my_struct *s, int t_data) {
#ifdef MY_STRUCT_MAGIC
  s->magic = MY_STRUCT_MAGIC;
#endif
  s->my_data = t_data;
}

my_struct *my_struct_cast(void *vs) {
  my_struct *s = vs;
#ifdef MY_STRUCT_MAGIC
  assert(MY_STRUCT_MAGIC == s->magic);
#endif
  return s;
}

由于包含const-casting,它有更多的代码,但我认为你明白了。

如果你想知道test_ptr是否指向aray成员,你必须这样检查:test_ptr >= array && test_ptr < &array[sizeof(array)/sizeof(array[0])])。如果指针来自void,char或某种dangerout ariyhmetic,你也可以检查test_ptr % sizeof(array[0])

如果你想知道一个指针指向有效的内存&#34;是否已分配&#34;通过你的程序,你将不得不拦截allocs函数,保存返回的块指针&amp;大小,并像前面的例子一样计算。