我有N个静态分配的结构。检查指针是否指向有效结构
struct exemple{
...
}
struct exemple array[N];
struct exemple *test_ptr = 0x3; /* random address */
我可以检查test_prt是否指向有效地址?即它指向分配的一个“结构示例”。
我有N个静态分配的结构。检查指针是否指向有效结构
struct exemple{
...
}
struct exemple array[N];
struct exemple *test_ptr = 0x3; /* random address */
我可以检查test_prt是否指向有效地址?即它指向分配的一个“结构示例”。
只能通过执行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
}
但在一般情况下,你不能只是指针指向测试特定的有效位置您。由你来负责照顾它所指的地方。它也可以有非空值,但指向无效的位置,例如:
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
你不能。你必须知道。如果你正确地管理你的指针,这不是一个问题。一个好习惯就是一旦销毁它们指向的对象,就总是设置指向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 */
结果将取决于您的实施/系统。
没有语言方法,但在某些情况下,您可以尝试在结构的某些点处具有一些已知值。如果指向的内存位置具有这些值,则可以将其视为有效 - 但当然,您没有任何担保。但是当你创建结构时,你需要编写自己的函数,以及何时将其销毁(通过在释放内存之前填充零)。这是一个非常周的解决方法 - 但是如果你连接另一个度量并接受开销,它会降低不正确的程序行为的概率。
有时它被称为安全cookie。
当然有可能使它变得更加复杂 - 在某些位置上,只有这些饼干有偏移量。它使内存中的随机位置不太可能具有这样的数据链:)
一般来说,不,你不能测试指针是否有效。
但是,如果你想知道,如果一个指针指向一个数组的元素,您可以:
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
}
这工作,因为数组连续地分配。
我不知道我是否正确地得到您的问题。
如果你想知道,如果一个指针指向某种类型的结构(投我的结构,以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指向阿雷成员,你必须检查这种方式:test_ptr >= array && test_ptr < &array[sizeof(array)/sizeof(array[0])])
。如果指针来自void,char或者某种危险的ariyhmetic,那么你也可以检查test_ptr % sizeof(array[0])
如果你想知道指针是否指向你的程序“曾经分配过”的有效内存,你将不得不拦截分配函数,保存返回的块指针大小,并像上例那样进行计算。
我知道我可以做阵列检查,但我想知道是否有更多的直接方法。谢谢 – alessiovolpe
@alessiovolpe不幸的是,没有,这就是为什么C是控制语言:) – tilz0R
这对于大型阵列来说效率非常低。 **有更直接的方式,@alessiovolpe。 – alain