rafiya
rafiya

Reputation: 97

Can I use typecasts in C to get the size of memory at a pointer to an address?

I'm trying to use shared memory segments in POSIX and am having a lot of trouble figuring out if there is memory at a certain address.

I saw a solution that uses file_size = *(size_t *)ptr

Where ptr is the returned pointer from some call to mmap (.... )

I don't really understand how this works. What does *(size_t *) typecasting do? I assume it (size_t)*var would cast the value at pointer var to a size_t type. But then, when I put another asterisk... this would give me a pointer again, wouldn't it?

Upvotes: 2

Views: 316

Answers (1)

Keith Thompson
Keith Thompson

Reputation: 263627

There is no general way to determine the size of the allocated memory to which a given pointer points. or even whether it points to a valid object. There might be some system-specific ways to determine something similar, but they're likely to be unreliable -- and they can't determine that a pointer points to a valid object, but not to the one that it's supposed to point to.

You'll just have to keep careful track of this information yourself.

The method you describe:

file_size = *(size_t *)ptr;

can work if the memory happens to have been allocated by something that specifically stores the size at the beginning of the allocated region -- but only if you already know that ptr is valid.

ptr could be a pointer of any type (other than a function pointer). The cast (size_t *) converts the value of ptr so you can treat it as a pointer to a size_t object (size_t is an unsigned integer type used to represent sizes). Dereferencing that size_t* value with the * dereference operator gives you the value of the size_t object.

Here's an example of a hypothetical allocation function that might work this way:

void *allocate(size_t size) {
    void *result = malloc(sizeof (size_t) + size);
    if (result != NULL) {
        *(size_t*)result = size;
    }
    return result;
}

and a function that gives you the currently allocated size:

size_t curr_size(void *ptr) {
    return *(size_t*)ptr;
}

NOTE that this ignores alignment issues. If you're allocating memory for something that requires stricter alignment that size_t does, this can fail badly.

Upvotes: 2

Related Questions