Different sizes of data and function pointers on a machine -- void*return type of malloc, calloc, an

K

Keith Thompson

Myth__Buster said:
Yeah, I know, that's the usual pattern - when we allocate a certain
chunk of memory for an object of type T, we would be storing the
respective malloc's return value in an object of type T*. No questions
on that beginner's aspect.

In my question being discussed, we are allocating space for a function
pointer which might *not* be of same size as that of a data pointer on
some machines. No questions on the allocation. It's fine and clear to
me. But, the data pointer(void*) being returned by malloc will be
improper to access the allocated space for the function pointer. And
hence, I would like to see a relevant note under malloc's
documentation.

Of course, I would like to allocate space for a function pointer using
malloc without any dependency on any third-variable such as struct
variable, etc, and use it thereafter(regarding the usage, that will be
another story. I am interested in getting a proper pointer in the
first place from malloc). And yeah, in the realms of C, allocating
space for a function is meaningless as we know sizeof a function makes
no sense. :)

It *doesn't matter* whether the object being allocated happens to
have the same size as a void*.

Suppose you're allocating a struct object rather than a
pointer-to-function object. Suppose void* is 4 bytes, and your
structure is 1024 bytes. The issues are exactly the same as in the
case you're looking at.

For struct allocation, you need to convert (probably implicitly)
the void* value returned by malloc() to a pointer to the struct.

For pointer-to-function allocation, you need to convert (probably
implicitly) the void* value returned by malloc() to a pointer to
the pointer-to-function.

Pay careful attention to the parallel construction of the two preceding
paragraphs.

I think the fact that the object you're allocating is a pointer is
causing you to confuse the pointer object being allocated with a
pointer *to* that pointer object. They're at two different levels
of indirection, and their relative sizes are not relevant.

You're imagining a special case where there really isn't one.
 
E

Eric Sosman

[...]
In my question being discussed, we are allocating space for a function pointer which might *not* be of same size as that of a data pointer on some machines. No questions on the allocation. It's fine and clear to me. But, the data pointer(void*) being returned by malloc will be improper to access the allocated space for the function pointer. And hence, I would like to see a relevant note under malloc's documentation.

Thanks to Ben Bacarisse, I think I see what you're confused
about. (It wasn't evident from the original erroneous code: Half
the respondents fixed the error by imagining a change to one side
of the assignment, and half chose to change the other. That's a
fundamental problem with invalid code: There may be many different
correct codes at small "edit distances" from the original, with
each edit corresponding to a different idea of "the error.")

Anyhow: A function pointer is a data type and has a sizeof, and
malloc() is perfectly capable of allocating space to hold objects
of that type. The `void*' returned by malloc() is entirely proper
for accessing the allocated space; you can store function pointer
values in that space and retrieve them from it, and (if they're
valid values) you can make calls through them to actual functions.
A note saying "malloc() cannot allocate space for function pointers"
would not be a clarification, it would be incorrect.

What malloc() cannot return is a pointer to memory capable of
holding a function. Put another way, malloc() cannot return a
pointer to an actual, callable function, nor to memory that might
possibly hold such a thing. (As far as C is concerned, functions
don't inhabit "memory" at all.)

You seem hung up on the (possible) difference between the
sizeof a function pointer and sizeof(void*), but there's no reason
to be alarmed. I'm sure you use malloc(sizeof(struct foo)) without
trouble, even when sizeof(struct foo) != sizeof(void*). The size
of a pointed-at thing and the size of the pointer to it need not
be related at all -- and that's the case when the pointed-at thing
is a function pointer, too.
 
O

Owen Jacobson

Achievement : Clarity and completeness of malloc's behavior in malloc's
documentation. More appropriately, a word of caution similar to this -
In C, malloc when used to directly allocate memory for function
pointers(without any third-variable's allocation such as encompassing
struct variable, etc) on machines wherein the data and function
pointers are of different sizes, the return data pointer wouldn't be a
proper pointer with which the entire memory allocated for function
pointer could be accessed. Hence, care should be exercised before the
allocated memory could be used. (On similar lines, the applicable
alternative approaches can be mentioned therein to accomplish the same
and thereby help the reader/programmer).

Given the declaration
int (*p)(void) = malloc(sizeof(int (*)(void)));
and reading it "for intent" rather than as written:
- 'p' identifies a function pointer value.
- malloc is being (mis-)used to allocate memory for a function, and is
incorrectly being expected to return a pointer to that function.

The second thing is flatly nonsensical. Nothing malloc could reasonably
do with the block of memory it allocates could make that block into a
function, and C does not provide tools for composing functions in
random blocks of memory, so there's no way subsequent code could turn
the block into a legitimate function either.

I don't know how you've gotten to "malloc is allocating a function
pointer" here. It's not: it's allocating a block of memory, then
*returning* a (value) pointer to that block. Trying to interpret the
pointed-to block as a function will at best crash your program, so the
returned pointer cannot be interpreted as a pointer to a function.
(Ignoring the case where malloc returns a null pointer.)

The only sensible values for function pointers (which 'p' already
identifies, without any need for dynamic allocation of a pointer-sized
block) are the values obtainable from the addresses of functions in
your program:

int random_number(void) {
return 4; /* generated by fair die roll */
}

int main(void) {
int (*p)(void) = random_number;
/* and so on */
return 0;
}

It's completely unnecessary to note in the docs that malloc can't
return a function pointer for the same reason that's unnecessary to
mention that memcpy can't receive a function pointer as an argument:
it's taken as given that if you use function pointers, you understand
how they're different from value pointers, and how the pointed-to
entities differ in both allocation and behaviour. Non-null function
pointers are *never* compatible with value pointers, and vice versa, as
far as I know.

If you really wanted to use malloc to "allocate a function pointer"
(for whatever unlikely reason), you'd need to add another step of
indirection, and declare 'p' as a pointer to a function pointer:

int (**p)(void) = malloc(sizeof(*p));
if (p != NULL) {
*p = random_number;
/* and so on */
}

Here, malloc allocates a block at least the size of a function pointer,
and returns a pointer *to* that block. I can't imagine why you'd write
code this way, though.

-o
 
N

Nobody

Now, would like to reiterate myself - malloc() returns a void*(data
pointer as always known) even when we have allocated memory for a function
pointer on a machine wherein data and function pointers are of different
sizes. This behavior of malloc appears to me as improper
Why?

and hence I am questioning its generality of returning a void*(data
pointer) always.

All pointers are data, and all pointers to data are data pointers,
including pointers to function pointers.

If you malloc() space for a function pointer, malloc returns a pointer to
that space. Whether or not you actually use that space to hold a function
pointer is irrelevant.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top