BionicSheep
BionicSheep

Reputation: 444

Convert string formatted memory address to pointer in C

I have a text file with the memory addresses of certain components of a program. For instance part of that text file looks like this:

00400000-0040b000

or

7f9ae612f000-7f9ae62ee000

I have already read the file into my program and assigned a char[] with the first address (00400000).

I also have a structure with a null pointer

struct myStruct
{
    void *address;
}

And I would like the pointer *address to have the value of 0x00400000, how would I do this?

Thank you for your help.

Upvotes: 1

Views: 4044

Answers (3)

user6754053
user6754053

Reputation:

Source:

First of all %x writes unsigned int. There is no guarantee that pointer size = unsigned int size.

As there is no format specifier which takes uintptr_t, you need to manualy check your pointer size in program and then select correct format specifier.

Therefore, to comply with the standard, you have to manually use the sizeof operator on void * and unsigned int and compare them. If they are equal, you can use %x as the format.

Otherwise, you need to take appropriate action, and use a different format.

Of course, if this is just a test project, it won't matter to do a dynamic check at runtime. Just hardcode it to the correct value. Be sure to leave a FIXME though, so you can come back and add dynamic checking later.

Additionally,

We discussed in the comments about the format specifiers, and you specified that %lx had correct results. Since it is guarenteed that %lx can print a value of at least uint32_t, your void * must be at least the size of uint32_t.

Additionally number 2,

Source.

If you aren't happy with the implementation-defined behaviour of %p, then use C99 <inttypes.h> and uintptr_t instead:

printf("0x%" PRIXPTR "\n", (uintptr_t)your_pointer);

Please note that the above solution requires C99 to work properly.

Upvotes: 0

Remy Lebeau
Remy Lebeau

Reputation: 595827

Use sscanf() to parse the string as a hex integer and then typecast the resulting integer to a void* pointer. For example:

char str[] = "00400000";
unsigned long ul;
struct myStruct s;

sscanf(str, "%lx", &ul);
s.address = (void*) (uintptr_t) ul;

Upvotes: 1

chux
chux

Reputation: 153348

If the same instance of the program printed "00400000-0040b000" then reading a void* back via scanf("%p"... is possible. Else the result is undefined.

p specifier:

Matches an implementation-defined set of sequences, which should be the same as the set of sequences that may be produced by the %p conversion of the fprintf function. The corresponding argument shall be a pointer to a pointer to void. The input item is converted to a pointer value in an implementation-defined manner. If the input item is a value converted earlier during the same program execution, the pointer that results shall compare equal to that value; otherwise the behavior of the %p conversion is undefined. C11dr §7.21.6.2 12

struct myStruct x;
if (fscanf(stream, "%p", &x.address) == 1) Success();

Upvotes: 0

Related Questions