Newbie question about malloc

Discussion in 'C Programming' started by George, Dec 17, 2003.

  1. George

    George Guest

    Hello to everybody !!!
    Why am i getting always:
    size=4 (i understand this)
    length=3 (?????)
    when i'm executing the following programm?
    Should'nt i get always the number of bytes
    allocated by "malloc" ??? (in this example 16)
    Why is this happening?


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    main()
    {
    char* name;
    name=(char*)malloc(16);
    if (!name)
    {
    printf("Mem Alloc Error.");
    exit (0);
    }
    printf("size=%d \n",sizeof(name));
    printf("length=%d",strlen(name));
    free(name);
    return 0;
    }

    Many thanks in advance,George
    George, Dec 17, 2003
    #1
    1. Advertising

  2. George

    grobbeltje Guest

    George <> wrote:
    > size=4 (i understand this)
    > length=3 (?????)

    as far as i can see, you never define what is inside 'name',
    so it can contain whatever it wants. strlen searches for the
    first '\0' and happens to find one at the 4th positions (lucky you!).

    > main()
    > {
    > char* name;
    > name=(char*)malloc(16);
    > if (!name)
    > {
    > printf("Mem Alloc Error.");
    > exit (0);
    > }
    > printf("size=%d \n",sizeof(name));
    > printf("length=%d",strlen(name));
    > free(name);
    > return 0;
    > }


    you could try 'name=calloc(16,sizeof(char));' instead of the line
    with malloc, it should make strlen return 0.

    good luck!
    grobbeltje.
    --
    If you must choose between two evils, pick the one you've never tried before.
    grobbeltje, Dec 17, 2003
    #2
    1. Advertising

  3. George

    Lew Pitcher Guest

    George wrote:

    > Hello to everybody !!!
    > Why am i getting always:
    > size=4 (i understand this)
    > length=3 (?????)
    > when i'm executing the following programm?
    > Should'nt i get always the number of bytes
    > allocated by "malloc" ???


    No. See below

    > (in this example 16)
    > Why is this happening?
    >
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    >
    > main()
    > {
    > char* name;
    > name=(char*)malloc(16);
    > if (!name)
    > {
    > printf("Mem Alloc Error.");
    > exit (0);
    > }
    > printf("size=%d \n",sizeof(name));


    sizeof is a C operator that results in a size_t value indicating the size of
    the selected data item or type. You got 4 here because the C compiler you
    are using implements character pointers as 4-byte quantities.

    > printf("length=%d",strlen(name));


    strlen() is a C standard function that counts characters. It starts counting
    at the address pointed to by it's argument, and stops when it encounters the
    first '\0' character. The resulting value may have no correspondance to the
    size of the memory block allocated by your malloc() call.

    Your use here of strlen() has two flaws:
    1) You haven't initialized the block of memory pointed to by name, thus the
    memory contains unknown data. It is a programming error to attempt to
    call strlen() against an uninitialized data area.

    2) the returned value from strlen() does not represent the length of
    allocated memory. Instead, it represents the length of the string
    pointed to by it's argument. AFAIK, there is /no/ standard function that
    will accept a pointer to a malloc()ed array, and return the length of the
    malloc().


    > free(name);
    > return 0;
    > }
    >
    > Many thanks in advance,George



    --
    Lew Pitcher, IT Consultant, Application Architecture
    Enterprise Technology Solutions, TD Bank Financial Group

    (Opinions expressed here are my own, not my employer's)
    Lew Pitcher, Dec 17, 2003
    #3
  4. (George) wrote in
    news::

    > Hello to everybody !!!
    > Why am i getting always:
    > size=4 (i understand this)
    > length=3 (?????)
    > when i'm executing the following programm?
    > Should'nt i get always the number of bytes
    > allocated by "malloc" ??? (in this example 16)
    > Why is this happening?
    >
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    >
    > main()


    int main(void)

    > {
    > char* name;
    > name=(char*)malloc(16);


    name = malloc(16); /* no cast in C, only C++ */

    > if (!name)
    > {
    > printf("Mem Alloc Error.");
    > exit (0);

    return EXIT_FAILURE; /* why bother with exit */
    > }


    > printf("size=%d \n",sizeof(name));

    printf("size of pointer 'name'=%u\n", (unsinged int) sizeof name);

    > printf("length=%d",strlen(name));


    printf("length of initialized string is bogus=%u\n",
    (unsigned int) strlen(name));

    > free(name);
    > return 0;
    > }
    >
    > Many thanks in advance,George
    >


    Now try again.

    #define NEEDED_SIZE 1024

    int main(void)
    {
    int failure = EXIT_FAILURE;
    char *pName = malloc(NEEDED_SIZE);

    if (pName)
    {
    /* Initialize to something
    */
    strcpy(pName, "Hello world");

    printf("Size of memblock at pName is %d\n", NEEDED_SIZE);
    printf("Len of string in memblock is %u\n",
    (unsigned int) strlen(name));

    free(pName);
    failure = EXIT_SUCCESS;
    }

    return failure;
    }

    --
    - Mark ->
    --
    Mark A. Odell, Dec 17, 2003
    #4
  5. George

    Artie Gold Guest

    George wrote:
    > Hello to everybody !!!
    > Why am i getting always:
    > size=4 (i understand this)
    > length=3 (?????)


    See below.

    > when i'm executing the following programm?
    > Should'nt i get always the number of bytes
    > allocated by "malloc" ??? (in this example 16)


    No. That's just not how it works. There is no portable way to know how
    many bytes were allocated given a pointer to memory.

    > Why is this happening?
    >
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    > main()

    int main(void)

    > {
    > char* name;
    > name=(char*)malloc(16);


    Lose the cast. It's unnecessary.

    > if (!name)
    > {
    > printf("Mem Alloc Error.");
    > exit (0);


    You probably want:

    exit EXIT_FAILURE;

    It failed, didn't it?


    > }
    > printf("size=%d \n",sizeof(name));


    The sizeof() operator returns the size of the object, which, in this
    case is an object of type `pointer to char'. On your system that size is
    evidently 4.

    > printf("length=%d",strlen(name));


    When you use malloc() to allocate memory, the contents of that memory is
    indeterminate -- so looking at it produces undefined behavior. It just
    so happens that in this particular case, the fourth `char' was 0 (or
    '\0'). Since you invoked undefined behavior, the result could have been
    *anything*, even things much too horrible to mention at this hour of the
    morning.

    > free(name);
    > return 0;
    > }
    >
    > Many thanks in advance,George


    Fair enough. ;-)

    HTH,
    --ag

    --
    Artie Gold -- Austin, Texas
    Oh, for the good old days of regular old SPAM.
    Artie Gold, Dec 17, 2003
    #5
  6. Lew Pitcher <> spoke thus:

    > You got 4 here because the C compiler you
    > are using implements character pointers as 4-byte quantities.


    Just FMI, is this a choice of the compiler or the implementation?

    > The resulting value may have no correspondance to the
    > size of the memory block allocated by your malloc() call.


    No "may" about it - the values are independent, yes?

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
    Christopher Benson-Manica, Dec 17, 2003
    #6
  7. George

    Lew Pitcher Guest

    Christopher Benson-Manica wrote:

    > Lew Pitcher <> spoke thus:
    >
    >
    >>You got 4 here because the C compiler you
    >>are using implements character pointers as 4-byte quantities.

    >
    >
    > Just FMI, is this a choice of the compiler or the implementation?
    >
    >
    >>The resulting value may have no correspondance to the
    >>size of the memory block allocated by your malloc() call.

    >
    >
    > No "may" about it - the values are independent, yes?


    Yes, mostly.

    I thought of a caveat that I didn't want to write for fear of confusing the
    issue, and not phrasing it correctly enough for the pedants in the group.

    The caveat is that a programmer could write

    strcpy(name,pointer_to_initialization_string);

    (given proper definition and values for name and
    pointer_to_initialization_string) and initialize the memory block.

    Given that this results in /correct/ initialization, then strlen() would
    result in a value less than the size of the allocated memory block.

    However, assuming that this results in an /incorrect/ initialization (if,
    for instance, pointer_to_initialization_string points to a string that is
    larger than the target block of memory), then the results of strlen() will
    be somewhat indeterminate (I'll let the language lawyers here decide whether
    it would be an error condition, or "implementation defined" or "undefined").
    /If/ strlen() returns a value in this case, it /may/ have some
    correspondance to the size of the memory block allocated by the malloc() call.

    And that's what I didn't want to expound on. <grin>




    --
    Lew Pitcher, IT Consultant, Application Architecture
    Enterprise Technology Solutions, TD Bank Financial Group

    (Opinions expressed here are my own, not my employer's)
    Lew Pitcher, Dec 17, 2003
    #7
  8. George

    Lew Pitcher Guest

    Christopher Benson-Manica wrote:

    > Lew Pitcher <> spoke thus:
    >
    >
    >>You got 4 here because the C compiler you
    >>are using implements character pointers as 4-byte quantities.

    >
    >
    > Just FMI, is this a choice of the compiler or the implementation?


    Good question. I fear that I don't have a definitive answer for it though.

    I would expect that the compiler has some restrictions wrt the target
    platform, including restrictions on the size of pointers. Pointer sizes
    /can/ vary at the hardware, either by type of data pointed to, or as a
    result of execution environment limitations. The compiler may have to make
    a choice as to /which/ pointer size to allocate a pointer to. If there's no
    choice for the compiler to make, I'd expect that the pointer size is
    dictated by the implementation.

    --
    Lew Pitcher, IT Consultant, Application Architecture
    Enterprise Technology Solutions, TD Bank Financial Group

    (Opinions expressed here are my own, not my employer's)
    Lew Pitcher, Dec 17, 2003
    #8
  9. George wrote:

    > Hello to everybody !!!
    > Why am i getting always:
    > size=4 (i understand this)
    > length=3 (?????)
    > when i'm executing the following programm?
    > Should'nt i get always the number of bytes
    > allocated by "malloc" ??? (in this example 16)
    > Why is this happening?


    Here's a few more details about things that were glossed over in some of
    the replies.

    >
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <string.h>
    >
    > main()


    int main(void)

    "Implicit int" no longer exists in C. Under the latest standard you must
    specify the return type for all functions. In the case of main(), the
    return type must be 'int' (contrary to popular belief, 'void' has never
    been an acceptable return type for main() in any version of C).

    As for the voided parameter list, you should never use empty parameter
    lists in C unless you really know what you are doing. In C (unlike C++)
    an empty parameter list is very different from a void parameter list,
    and empty parameter lists can be very dangerous.

    > {
    > char* name;
    > name=(char*)malloc(16);


    It's generally recommended to NOT cast the return from malloc(). At
    least one very notable book on C incorrectly states that the cast is
    required, but it is not.

    The main reasons to not cast are: 1) It can suppress a useful
    diagnostic, thus hiding an error in the code (the error in question is a
    failure to provide a correct declaration for malloc() - the result of
    forgetting to #include <stdlib.h>). 2) The cast is an extra maintenance
    concern. If the type of 'name' were to change (say, to unsigned char, or
    wchar_t), you'd need to locate and fix every cast expression involving
    'name'.

    The comp.lang.c-approved method of calling malloc() looks like this:

    name = malloc(16 * sizeof(*name) );

    (Alternatively, remove the parens on the sizeof operator - they aren't
    necessary in this case.)

    This form automatically adjusts to changes in the type of 'name', and is
    generally more difficult to get wrong than other forms.

    > if (!name)
    > {
    > printf("Mem Alloc Error.");


    No one else mentioned this (that I saw), but a portable program needs to
    terminate its output with a newline:

    printf("Mem Alloc Error.\n");

    It's not uncommon for the last line of output to mysteriously disappear,
    or to appear with the system prompt tagged onto the end if it is not
    correctly terminated.

    Also, error output should usually go to the standard error stream:

    fprintf(stderr, "Mem Alloc Error.\n");

    > exit (0);
    > }
    > printf("size=%d \n",sizeof(name));
    > printf("length=%d",strlen(name));


    Both of these printfs are wrong. As before, you should end your lines
    with a newline character, but more importantly you have used the wrong
    format specifiers. This can be a very serious problem, and most
    compilers won't warn you about it.

    Both sizeof and strlen give a result of type size_t. size_t is an
    unsigned type. The %d format specifier is for (signed) int ONLY. It's
    possible that size_t could be an alias for unsigned int, but not signed
    int. Therefore, %d can never be the correct format specifier for a size_t.

    Keep in mind that printf is stupid. It cannot determine the actual types
    of the objects you pass it. It relies completely on you telling it the
    correct type. If you lie to it about the type, all bets are off. Stack
    corruption leading to a program crash or worse is very likely. Even if
    it "seems to work", bad things may be happening that aren't easily
    observed - mysterious, very difficult to find bugs can pop up. The
    behavior can appear random, and may be completely different on a
    different system, or when using a different compiler.

    In other words, it's very important to get your format strings right.
    Always double-check them.

    In this case, there probably isn't a format string you can use for
    size_t. C99 introduced %zu for this purpose, but you probably aren't
    using a C99 compiler. The safest way to print a size_t is to cast it to
    a known type first:

    printf("length=%lu\n", (unsigned long)strlen(name));

    This is guaranteed safe in C versions prior to C99, since size_t can be
    no wider than unsigned long. As of C99, size_t can be wider (it can even
    be wider than the new 'long long' type, I think), so this is not
    completely safe under C99 (it is safe in the sense that it cannot lead
    to undefined behavior, but the results may be inaccurate).

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
    Kevin Goodsell, Dec 17, 2003
    #9
  10. George

    Chris Torek Guest

    In article <news:>
    George <> writes:
    >Should'nt i get always the number of bytes
    >allocated by "malloc" ??? (in this example 16)


    In addition to the other responses so far, I might point out that
    while the *call* says:

    malloc(16)

    there is no guarantee that you actually *got* 16 bytes, even if
    the returned pointer is NULL. Suppose, for instance, that for some
    reason your implementation has chosen never to hand out less than
    some minimum number of bytes at a time via malloc(). The malloc()
    on that system might include code like:

    if (size < MIN_MALLOC_SIZE)
    size = MIN_MALLOC_SIZE;

    near the top, with MIN_MALLOC_SIZE greater than 16. Thus, you
    might have gotten 20, 24, 32, or even more bytes. (Real malloc()s
    often do contain this kind of code, so this is not a purely
    theoretical issue.)

    C has no "how much did I malloc() with this non-NULL pointer that
    is suitable for use as an argument to free()" function. Such a
    function might be useful, but if one were to be proposed for addition
    to a future C standard (or any other "non-C" standard that acts as
    a sort of add-on, such as the POSIX system-function bindings like
    readdir() and such), we would have to decide: "Does this function
    return the argument passed to malloc(), or does it return the actual
    number of bytes malloc() handed out even if that was a larger
    number?"

    Also, this:

    > char* name;

    ...
    > printf("size=%d \n",sizeof(name));


    printed 4. (Note that strlen() returns a size_t value, which is not
    an int value; anything might have been printed, but for luck. Whether
    this is "good luck" or "bad luck" depends on one's point of view...)
    In a later followup he asked:

    >... is this a choice of the compiler or the implementation?


    The only correct answer to this is "yes", because it might be either
    one. :) (I assume here "implementation" really means "hardware
    for which the C compiler compiles machine-level code.") Computer
    hardware often suggests (with varying degrees of strength) particular
    implementations for C code, but C compilers are not required to
    produce "sensible" code, merely "code that obeys the requirements
    of the C standard". As such, a compiler for a machine with 32-bit
    pointers could generate 16-bit-pointer code (that can only address
    65536 bytes at a time) and "run" that code via an interpreter that
    simulates some other machine that only has 16-bit pointers.

    (This, too, is not purely theoretical -- it is how emulators work.
    One might either use a cross-compiler that runs native and produces
    code for the emulated hardware, or even run under the emulator an
    old "native" C compiler that works on the emulated machine. In
    the latter case one might reasonably claim that the "machine" really
    does have 16-bit pointers; the cross-compiler case is more
    interesting, particularly if it is the cross-compiler that emits
    the emulator, and can optionally run some code "native" intermixed
    with other code "emulated".)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Dec 17, 2003
    #10
  11. George

    Ben Pfaff Guest

    Christopher Benson-Manica <> writes:

    > "implementation" means that I'm fuzzy on my terms :) The C compiler
    > *is* the implementation, then...?


    Yes, although the term "implementation" also includes the linker,
    the C library, and execution environment (anything else?), or at
    least those bits of them visible to a strict conforming program.

    C99 only contains the word "compiler" once, and that's in a
    footnote so it's not strictly part of the standard.
    --
    "Large amounts of money tend to quench any scruples I might be having."
    -- Stephan Wilms
    Ben Pfaff, Dec 17, 2003
    #11
  12. Chris Torek <> spoke thus:

    > (I assume here "implementation" really means "hardware
    > for which the C compiler compiles machine-level code.")


    "implementation" means that I'm fuzzy on my terms :) The C compiler
    *is* the implementation, then...?

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
    Christopher Benson-Manica, Dec 17, 2003
    #12
  13. Ben Pfaff <> spoke thus:

    > Yes, although the term "implementation" also includes the linker,
    > the C library, and execution environment (anything else?), or at
    > least those bits of them visible to a strict conforming program.


    So would you say, then, that the implementation is the set of software
    applications (compiler, linker, library, OS, etc.) responsible for
    creating executable code (and executing that code) from a C source
    file?

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
    Christopher Benson-Manica, Dec 17, 2003
    #13
  14. George

    Ben Pfaff Guest

    Christopher Benson-Manica <> writes:

    > Ben Pfaff <> spoke thus:
    >
    > > Yes, although the term "implementation" also includes the linker,
    > > the C library, and execution environment (anything else?), or at
    > > least those bits of them visible to a strict conforming program.

    >
    > So would you say, then, that the implementation is the set of software
    > applications (compiler, linker, library, OS, etc.) responsible for
    > creating executable code (and executing that code) from a C source
    > file?


    The standard defines "implementation":

    1 implementation
    particular set of software, running in a particular
    translation environment under particular control options,
    that performs translation of programs for, and supports
    execution of functions in, a particular execution
    environment

    --
    Just another C hacker.
    Ben Pfaff, Dec 17, 2003
    #14
  15. Re: [OT] Newbie question about malloc

    Mark A. Odell wrote:
    (snip)

    > failure = EXIT_SUCCESS;


    <just-kidding>
    Err... Is success really a failure ?-)
    </just-kidding>

    Bruno
    Bruno Desthuilliers, Dec 17, 2003
    #15
  16. Re: [OT] Newbie question about malloc

    Bruno Desthuilliers <> wrote in
    news:3fe0cbb4$0$22330$:

    >> failure = EXIT_SUCCESS;

    >
    > <just-kidding>
    > Err... Is success really a failure ?-)
    > </just-kidding>


    Yeah, it is kind of confusing. Usually I have a 'failures' return and set
    it to 0 for "no failures" and non-zero to indicate a failure. I suppose
    exit_code would have been better.

    --
    - Mark ->
    --
    Mark A. Odell, Dec 17, 2003
    #16
  17. Re: [OT] Newbie question about malloc

    On Wed, 17 Dec 2003 22:51:59 +0100, in comp.lang.c , Bruno
    Desthuilliers <> wrote:

    >Mark A. Odell wrote:
    >(snip)
    >
    >> failure = EXIT_SUCCESS;

    >
    ><just-kidding>
    >Err... Is success really a failure ?-)
    ></just-kidding>


    Well, MS helpfully define a macro ERROR_SUCCESS in winerror.h.

    Which, many would say, perfectly describes Windows...

    --
    Mark McIntyre
    CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
    CLC readme: <http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html>


    ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
    http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
    ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
    Mark McIntyre, Dec 17, 2003
    #17
  18. Christopher Benson-Manica <> writes:
    > Lew Pitcher <> spoke thus:
    >
    > > You got 4 here because the C compiler you
    > > are using implements character pointers as 4-byte quantities.

    >
    > Just FMI, is this a choice of the compiler or the implementation?


    That's not really an either/or question; the compiler is part of the
    implementation.

    It's up to the compiler (more precisely, to the authors of the
    compiler) to determine the size of a pointer, but that is influenced,
    and often mandated, by the underlying hardware (and, to a lesser
    extent, by the operating system).

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
    Schroedinger does Shakespeare: "To be *and* not to be"
    (Note new e-mail address)
    Keith Thompson, Dec 18, 2003
    #18
  19. Re: [OT] Newbie question about malloc

    Mark McIntyre <> spoke thus:

    > Well, MS helpfully define a macro ERROR_SUCCESS in winerror.h.


    Regrettably, some of the code I'm working with includes ctErrSuccess
    in an enumerated error code type...

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
    Christopher Benson-Manica, Dec 18, 2003
    #19
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John
    Replies:
    13
    Views:
    685
  2. ravi
    Replies:
    0
    Views:
    439
  3. Peter
    Replies:
    34
    Views:
    1,916
    Richard Tobin
    Oct 22, 2004
  4. porting non-malloc code to malloc

    , Feb 18, 2005, in forum: C Programming
    Replies:
    3
    Views:
    468
    Walter Roberson
    Feb 19, 2005
  5. Johs32

    to malloc or not to malloc??

    Johs32, Mar 30, 2006, in forum: C Programming
    Replies:
    4
    Views:
    313
    Captain Winston
    Mar 30, 2006
Loading...

Share This Page