Doubt with char* and char[]

Discussion in 'C Programming' started by Kamui Shirow, Jun 5, 2007.

  1. Kamui Shirow

    Kamui Shirow Guest

    Hello!

    I will write a snippet to illustrate my doubt:

    snippet 1:
    void foo( int l )
    {
    char* tmp;
    tmp = (char*) malloc( l * sizeof( char ) );

    // DO SOMETHING

    free( tmp );

    }

    snippet 2:
    void foo( int l )
    {
    char tmp[l];

    // DO SOMETHING

    }

    What is the difference in advantage if I use snippet 1 or 2?

    Thanks in advance!
     
    Kamui Shirow, Jun 5, 2007
    #1
    1. Advertising

  2. "Kamui Shirow" <> schrieb im Newsbeitrag
    news:...
    > Hello!
    >
    > I will write a snippet to illustrate my doubt:
    >
    > snippet 1:
    > void foo( int l )
    > {
    > char* tmp;
    > tmp = (char*) malloc( l * sizeof( char ) );

    drop the cast and add #include s<tdlib.h>. Also sizeof (char) is 1 by
    definition
    Also you'd need to check malloc's return value to detect failure.

    > // DO SOMETHING
    >
    > free( tmp );
    >
    > }
    >
    > snippet 2:
    > void foo( int l )
    > {
    > char tmp[l];
    >
    > // DO SOMETHING
    >
    > }
    >
    > What is the difference in advantage if I use snippet 1 or 2?

    Snippet 2 requires far less typing and you can't accidently forget to call
    free(), so it's less prone to memory leaks.

    Bye, Jojo
     
    Joachim Schmitz, Jun 5, 2007
    #2
    1. Advertising

  3. Kamui Shirow

    Ben Pfaff Guest

    Kamui Shirow <> writes:

    > snippet 1:
    > void foo( int l )
    > {
    > char* tmp;
    > tmp = (char*) malloc( l * sizeof( char ) );


    sizeof(char) is always 1, so it's unnecessary to multiply by it.

    I don't recommend casting the return value of malloc():

    * The cast is not required in ANSI C.

    * Casting its return value can mask a failure to #include
    <stdlib.h>, which leads to undefined behavior.

    * If you cast to the wrong type by accident, odd failures can
    result.

    In unusual circumstances it may make sense to cast the return value of
    malloc(). P. J. Plauger, for example, has good reasons to want his
    code to compile as both C and C++, and C++ requires the cast, as he
    explained in article <9sFIb.9066$>.
    However, Plauger's case is rare indeed. Most programmers should write
    their code as either C or C++, not in the intersection of the two.


    > // DO SOMETHING
    >
    > free( tmp );
    >
    > }
    >
    > snippet 2:
    > void foo( int l )
    > {
    > char tmp[l];
    >
    > // DO SOMETHING
    >
    > }
    >
    > What is the difference in advantage if I use snippet 1 or 2?


    Snippet 1 gives the code an opportunity to recover if the memory
    for tmp cannot be allocated. In snippet 2, the program yields
    undefined behavior and probably crashes if memory is unavailable.

    Snippet 1 has the opportunity to extend the lifetime of the array
    beyond the function's return. On the other hand, in snippet 2
    the programmer can't forget to call free.

    Many compilers do not yet implement the variable-length array
    support from C99 that is required snippet 2 to compile.

    I'd use the form of snippet 1 unless I knew that my code would
    never be ported to a pre-C99 compiler. In practice, that means
    that my code rarely if ever uses variable-length arrays.
    --
    Ben Pfaff
    http://benpfaff.org
     
    Ben Pfaff, Jun 5, 2007
    #3
  4. Kamui Shirow said:

    > Hello!
    >
    > I will write a snippet to illustrate my doubt:
    >
    > snippet 1:
    > void foo( int l )
    > {
    > char* tmp;
    > tmp = (char*) malloc( l * sizeof( char ) );
    >
    > // DO SOMETHING
    >
    > free( tmp );
    >
    > }


    Better:

    #include <stdlib.h>

    void foo(size_t n)
    {
    char *tmp = malloc(n * sizeof *tmp);
    if(tmp != NULL)
    {
    /* do something */
    free(tmp);
    }
    }

    > snippet 2:
    > void foo( int l )
    > {
    > char tmp[l];
    >
    > // DO SOMETHING
    >
    > }
    >
    > What is the difference in advantage if I use snippet 1 or 2?


    Snippet 1 doesn't require C99, and gives you control over failure.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, Jun 5, 2007
    #4
  5. In article <>,
    Kamui Shirow <> wrote:

    >I will write a snippet to illustrate my doubt:


    >snippet 1:
    >void foo( int l )
    >{
    > char* tmp;
    > tmp = (char*) malloc( l * sizeof( char ) );
    > // DO SOMETHING
    > free( tmp );
    >}


    >snippet 2:
    >void foo( int l )
    >{
    > char tmp[l];
    > // DO SOMETHING
    >}


    >What is the difference in advantage if I use snippet 1 or 2?


    Snippet 2 relies on Variable Length Arrays (VLA), which are part
    of C99 but not part of C89. I have not used VLA myself, but reading
    some of the other postings here, it sounds as if there are a noticable
    number of compilers which either do not accept VLA at all or else
    implement them differently than the C99 standard; in particular, I
    believe people have said that gcc does something with VLA than
    the C99 standard.

    I have not looked at VLA, so I do not know what the largest
    permitted array is.


    Snippet 1 has a useless cast -- you do not need the (char *)
    before the malloc(). That won't stop it from operating, that's
    just not good style. Snippet 1 will work on C89 whereas Snippet 2 will
    not work on C89. Snippet 1 has all the usual problems of malloc():
    Depending on how the malloc() is implemented, malloc() can sometimes
    be slow, or can sometimes not be able to find enough consequative
    available memory even though there is enough available memory if you
    could merge the seperate pieces of available memory together
    ("memory fragmentation"). And you've fallen into the classic pattern
    in using malloc(), in that you failed to check to see whether
    the system was able to give you the memory before you go ahead
    and use it. Oh yes, and sizeof(char) is *defined* to be 1 so
    there is no point in having the * sizeof(char) in the malloc().


    Both snippets have the problem that you do not check that the variable l
    is greater than 0 before you attempt to allocate space. Both would
    fail for foo(-1).

    You should also consider whether an "int" is large enough to
    express the amount of space that might be desired. That's going
    to depend on the context. It is legal in C implementations for
    the largest int to be merely 32767 so if you were planning to
    make foo available for a context in which someone might want
    to allocate (say) 50000 bytes, then you should change the
    user interface from specifying the size as an int . You could
    change the size to long or (not in pure C89) long long, but
    the most appropriate type for such a parameter is probably size_t .
    --
    If you lie to the compiler, it will get its revenge. -- Henry Spencer
     
    Walter Roberson, Jun 5, 2007
    #5
  6. "Joachim Schmitz" <> schrieb im Newsbeitrag
    news:f44ar4$ft8$...
    > "Kamui Shirow" <> schrieb im Newsbeitrag
    > news:...
    >> Hello!
    >>
    >> I will write a snippet to illustrate my doubt:
    >>
    >> snippet 1:
    >> void foo( int l )
    >> {
    >> char* tmp;
    >> tmp = (char*) malloc( l * sizeof( char ) );

    > drop the cast and add #include s<tdlib.h>. Also sizeof (char) is 1 by
    > definition
    > Also you'd need to check malloc's return value to detect failure.
    >
    >> // DO SOMETHING
    >>
    >> free( tmp );
    >>
    >> }
    >>
    >> snippet 2:
    >> void foo( int l )
    >> {
    >> char tmp[l];
    >>
    >> // DO SOMETHING
    >>
    >> }
    >>
    >> What is the difference in advantage if I use snippet 1 or 2?

    > Snippet 2 requires far less typing and you can't accidently forget to call
    > free(), so it's less prone to memory leaks.

    Outch, I've read the l for a 1...
    So as others pointed out Snippet 2 would only work in C99 or other
    C-Compilers with a non-standard extenion of VLAs

    Bye, Jojo
     
    Joachim Schmitz, Jun 5, 2007
    #6
  7. Kamui Shirow wrote:
    > Hello!
    >
    > I will write a snippet to illustrate my doubt:
    >
    > snippet 1:
    > void foo( int l )
    > {
    > char* tmp;
    > tmp = (char*) malloc( l * sizeof( char ) );


    1) It is always poor practice to cast the return value of malloc().
    Remember to #include <stdlib.h> and remember to use a C compiler.
    2) sizeof(char) is 1 by definition.

    Your line above can be reduced to
    tmp = malloc(i);

    There remain two more issues.
    3) it is possible that the type of tmp might change in future code.
    That makes a better form
    tmp = malloc(i * sizeof *tmp);
    4) Always check the return value. If it is NULL, then malloc failed:
    if (!tmp) {
    /* handle error */
    }

    > // DO SOMETHING
    > free( tmp );
    > }
    >
    > snippet 2:
    > void foo( int l )
    > {
    > char tmp[l];
    >
    > // DO SOMETHING
    >
    > }
    >
    > What is the difference in advantage if I use snippet 1 or 2?


    5) Snippet 2 is not legal without a C99 compiler. Most compilers are
    for C89 but not for C99. That is a huge difference.
    6) Snippet 2 will allocate tmp in automatic storage. In almost all
    implementations there is less room available for auto variables than for
    dynamically allocated ones.
    7) Snippet 2 does not allow you to check for the success or failure of
    the attempt to declare the array tmp. A failure is almost certainly a
    disaster.


    >
    > Thanks in advance!
    >
     
    Martin Ambuhl, Jun 6, 2007
    #7
  8. Martin Ambuhl <> wrote:

    > > tmp = (char*) malloc( l * sizeof( char ) );


    > Your line above can be reduced to
    > tmp = malloc(i);


    That would be malloc(l).

    --
    C. Benson Manica | I *should* know what I'm talking about - if I
    cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Jun 6, 2007
    #8
  9. Kamui Shirow

    Darko Guest

    Unbelievable how many people don't read other people's postings in the
    same thread. In this thread, I think 90% of information is
    unnecessarily repeated from the posting just above that one. C99, C99,
    C99, C99, Don't cast, Don't cast, Don't cast, Don't cast, sizeof char
    <=> 1, sizeof char <=> 1, sizeof char <=> 1, sizeof char <=> 1, sizeof
    char <=> 1, .............
     
    Darko, Jun 6, 2007
    #9
  10. Kamui Shirow

    Ben Pfaff Guest

    Darko <> writes:

    > Unbelievable how many people don't read other people's postings in the
    > same thread. In this thread, I think 90% of information is
    > unnecessarily repeated from the posting just above that one. C99, C99,
    > C99, C99, Don't cast, Don't cast, Don't cast, Don't cast, sizeof char
    > <=> 1, sizeof char <=> 1, sizeof char <=> 1, sizeof char <=> 1, sizeof
    > char <=> 1, .............


    Usenet propagation isn't instantaneous. Quite often I'll read an
    article, see no followups, reply, refresh the newsfeed, and
    there'll already be a couple of other followups.
    --
    int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    );}return 0;}
     
    Ben Pfaff, Jun 6, 2007
    #10
  11. Darko said:

    <snip>

    > C99, C99, Don't cast, Don't cast, Don't cast, Don't cast, sizeof char
    > <=> 1, sizeof char <=> 1, sizeof char <=> 1, sizeof char <=> 1, sizeof
    > char <=> 1, .............


    And *still* people ignore the advice. Incredible, isn't it?

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, Jun 6, 2007
    #11
  12. Darko <> wrote:

    > (I said, context restored:)


    >> That would be malloc(l).


    > Unbelievable how many people don't read other people's postings in the
    > (snip)


    My first inclination is to wonder exactly how your response follows
    from mine (unless my newsreader incorrectly threaded your post), but
    since you neglected to include any context in your post, it isn't
    clear exactly what you were replying to.

    --
    C. Benson Manica | I *should* know what I'm talking about - if I
    cbmanica(at)gmail.com | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Jun 6, 2007
    #12
  13. In article <>,
    Darko <> wrote:
    >Unbelievable how many people don't read other people's postings in the
    >same thread. In this thread, I think 90% of information is
    >unnecessarily repeated from the posting just above that one. C99, C99,
    >C99, C99, Don't cast, Don't cast, Don't cast, Don't cast, sizeof char
    ><=> 1, sizeof char <=> 1, sizeof char <=> 1, sizeof char <=> 1, sizeof
    >char <=> 1, .............


    Timestamps from the first four replies, in CDT (Central Daylight Time):

    13:42:20 13:45:13 13:54:29 13:54:33 (yes, only 4 seconds later.)

    The latter of those was a longer response, written by me -- so it
    was in preparation starting even before that first timestamp, 13:42:20 .

    After the initial burst of responses, there was another several hours
    later, something like 21:12; it did repeat a couple of points,
    but also made a couple of new points.

    --
    Okay, buzzwords only. Two syllables, tops. -- Laurie Anderson
     
    Walter Roberson, Jun 6, 2007
    #13
  14. Kamui Shirow

    Chris Dollin Guest

    Darko wrote:

    > Unbelievable how many people don't read other people's postings in the
    > same thread. In this thread, I think 90% of information is
    > unnecessarily repeated from the posting just above that one. C99, C99,
    > C99, C99, Don't cast, Don't cast, Don't cast, Don't cast, sizeof char
    > <=> 1, sizeof char <=> 1, sizeof char <=> 1, sizeof char <=> 1, sizeof
    > char <=> 1, .............


    The price of no duplicate answers is no answers at all.

    --
    "Go not to the Drazi for counsel, Unsaid /Babylon 5/
    for they will answer both 'green' and 'purple'."

    Hewlett-Packard Limited registered no:
    registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England
     
    Chris Dollin, Jun 7, 2007
    #14
    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. lovecreatesbeauty
    Replies:
    1
    Views:
    1,066
    Ian Collins
    May 9, 2006
  2. Bob Nelson

    doubt about doubt

    Bob Nelson, Jul 28, 2006, in forum: C Programming
    Replies:
    11
    Views:
    633
  3. Replies:
    0
    Views:
    568
  4. Peter Otten
    Replies:
    2
    Views:
    121
    Cousin Stanley
    Aug 10, 2013
  5. Terry Reedy
    Replies:
    0
    Views:
    120
    Terry Reedy
    Aug 10, 2013
Loading...

Share This Page