Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 检查指针是否指向有效的结构_C_Pointers_Struct - Fatal编程技术网

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

C 检查指针是否指向有效的结构,c,pointers,struct,C,Pointers,Struct,我有N个静态分配的结构 struct exemple{ ... } struct exemple array[N]; struct exemple *test_ptr = 0x3; /* random address */ 我可以检查test_prt是否指向有效地址吗?i、 它指向分配的一个“结构示例”。您只能通过执行指针!=NULL因为除“NULL”之外的任何内容都由有效指针处理 在您的情况下,要检查指针是否指向任何数组项,只能执行以下操作: size_t i = 0; int

我有N个静态分配的结构

struct exemple{
     ...
}

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

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

您只能通过执行
指针!=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
}

你不能。你必须知道。如果正确管理指针,这不是问题。一个好习惯是在销毁指针指向的对象后,始终将指针设置为
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


当然,这可能会使它变得更复杂——在某些位置,您只有对这些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
}
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指向数组的一个元素
}

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

我不知道我是否正确理解了您的问题

如果您想知道指针是否指向某种类型的结构(例如,将我的结构强制转换为
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;
}
#包括
结构我的结构{
#ifndef NDEBUG
#定义MY_STRUCT_MAGIC 0x1234abcd
uint64_t魔术;
#恩迪夫
int my_数据;
};
void init_struct(struct my_struct*s,int t_data){
#我的魔法
s->magic=MY_STRUCT_magic;
#恩迪夫
s->my_data=t_data;
}
我的结构*我的结构演员阵容(无效*vs){
我的结构*s=vs;
#我的魔法
断言(MY_STRUCT_MAGIC==s->MAGIC);
#恩迪夫
返回s;
}
因为包含了const casting,所以它的代码稍微多了一点,但我想你明白了


如果您想知道test_ptr是否指向一个aray成员,您必须这样检查:
test_ptr>=array&&test_ptr<&array[sizeof(array)/sizeof(array[0]))
。如果指针来自void、char或某种危险的ariyhmetic,您还可以检查
test\u ptr%sizeof(数组[0])


如果您想知道指针是否指向程序“曾经分配”的有效内存,则必须截取allocs函数,保存返回的块指针和大小,并像前面的示例一样进行计算。

我知道我可以进行数组检查,但我想知道是否有更直接的方法。thanks@alessiovolpe不幸的是,没有,这就是为什么C是控制语言:)对于大型数组来说,这是非常低效的。还有一种更直接的方法,@alessiovolpe@alain它效率很低,但除了检查指针是否为非空之外,根本没有其他方法来测试指针是否指向有效位置。即使指针是非空的,从它读取也是未定义的行为。@tilz0R通常是,但对于数组,请参阅我的答案;-)这在任何情况下都不行。如果你想要你的方法,你必须先减去:
((intptr\u t)test\u ptr-(intptr\u t)和array[0])%sizeof…
,最好是使用
test\u ptr感谢你指出缺少的减法@tilz0R。但是不需要使用
数组[N-1]
,因为可以指向超过数组末尾的一个,而不会导致UB。
#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;
}