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

Discussion in 'C Programming' started by Myth__Buster, Jun 25, 2012.

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

    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.
    Keith Thompson, Jun 25, 2012
    1. Advertisements

  2. Myth__Buster

    Eric Sosman Guest

    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.
    Eric Sosman, Jun 25, 2012
    1. Advertisements

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

    Owen Jacobson, Jun 26, 2012
  4. Myth__Buster

    Nobody Guest

    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.
    Nobody, Jun 26, 2012
    1. Advertisements

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 (here). After that, you can post your question and our members will help you out.