简体   繁体   中英

How to check if memory is accessible or not?

I am trying to debug a crash issue where memcpy is trying to access a memory location which does not exist and fails. Following is a reduced version of the problem code:

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.
}

My question is: is there a way I can check if memory is accessible before attempting the memcpy , or is there another protection mechanism to prevent the crash here? Would not checking **a cause a crash as well in this case?

There is no, portable way, to programmatically test if a pointer is pointing to valid accessible memory.

This is one reason for the highly recommended practice of always setting your pointers to NULL when they memory they were pointing to was free'ed and at initialization, so you have something to test against.

Would not checking **a cause a crash as well in this case?

Correct, all you're doing here is assigning the passed in value to a local then attempting to access it. If the local is bad, it's because the passed in value is bad. Garbage in, garbage out.


To address the code you provided:

   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

If someone passes you a garbage pointer in *a there's no way of checking (not platform independent anyway) if that can be accessed.

But if someone is passing a==NULL or *a==NULL you could at least check for that (Eric mentioned that first in his comment to the other answer):

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");
   }
}

Just for fun, a simplified version would be:

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");
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM