如何检查内存是否可访问?

4

我正在尝试调试一个崩溃问题,其中memcpy试图访问一个不存在的内存位置并失败了。以下是问题代码的简化版本:

void func_foo(int **a) {
   int *b, c;
   if (*a) {
       b = *a;
   }
   memcpy(&c, b, sizeof(int));//this crashes because address "b" is not accessible.
}

我的问题是:在尝试进行memcpy之前,是否有一种方法可以检查内存是否可访问?或者是否有其他保护机制可以防止崩溃?如果不检查**a,在这种情况下也会导致崩溃吗?


memcpy(&c, b, sizeof(int*)); - mf_
4
@mf_ 不对。 - user529758
4
不对,这也是错误的。他试图将'b'中的一个整数复制到'c'中。 - user529758
如果@a是垃圾,那么答案就取决于检查。 - mf_
让我们在聊天中继续这个讨论。点击此处进入聊天室 - mf_
显示剩余5条评论
2个回答

2

没有一种便携的方法可以编程地测试指针是否指向有效可访问的内存。

这是始终将指针设置为NULL的高度推荐做法之一,当它们指向的内存被释放并在初始化时,您就有了可以进行测试的东西。

在这种情况下不检查**a也会导致崩溃吗?

正确,你所做的只是将传入的值赋给一个本地变量,然后尝试访问它。如果本地变量是错误的,那么原因是传入的值是错误的。垃圾进去,垃圾出来。


针对您提供的代码:

   if (*a) {
       b = *a;
   }
   memcpy(&c, b, sizeof(int));//you really shouldn't be executing this at all unless
                              // you're setting b, so it should be within the if check 
                              // and only executed after b=*a

1
因为忽略了问题的关键点而被投票否决:问题中的代码使用了未初始化的 b。这可能是最初问题的原因。 - Eric Postpischil
1
@Eric - 几点建议:1)由于OP声明这不是实际代码,更像是“大象在走廊里”,我们不知道实际代码是否存在相同的问题。2)即使代码在设置b的检查范围内,也不能保证它不会引起问题。正如你所说,如果*aNULL,则不会设置b,但如果a*是垃圾,则b将被设置,我们仍然很可能在memcpy中崩溃。3)鉴于以上1和2点,您正确地指出了代码可以更简洁,因此我进行了修改。 - Mike

0

如果有人在*a中传递给您一个垃圾指针,没有任何办法检查(无论如何都不是平台独立的)是否可以访问该指针。

但是,如果有人传递a==NULL或*a==NULL,您至少可以检查一下(Eric在对其他答案的评论中首先提到了这一点):

void func_foo(int **a) 
{
   int *b= NULL, c;

   if (a!=NULL) {
       b = *a;
   }

   if (b!=NULL) {
       printf("about to access memory at address 0x%p\n", b);
       memcpy(&c, b, sizeof(int));//this crashes because address "b" is not accessible.
       // btw same as c= *b  or  c= **a; 
   }
   else {
       printf("someone passed us a null pointer either in a or *a\n");
   }
}

只是为了好玩, 简化版本如下:

void func_foo(int **a) 
{
   int c;

   if (a!=NULL && *a!=NULL) {
       c = **a;
   }
   else {
       printf("someone passed us a null pointer either in a or *a\n");
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接