String and null character

Discussion in 'C Programming' started by Chapman, Sep 15, 2003.

  1. Chapman

    Chapman Guest

    Some questions about strings: this is the extracted piece of my test code:

    /** **/

    char *arry;
    arry = malloc(30*sizeof(arry));

    arry[0] = 'B';
    arry[1] = 'S';
    arry[2] = 'c';

    /** **/

    The questions are:

    1. Now does the variable arry contain the null character immediately because
    of malloc?

    2. or I should append '0' at arry[3] ? (which in fact what I did next, but
    when testing the compiler without '\0', it worked (??)

    Because in both cases (whether I append '\0' or not), if I use the
    functions atoi or any other string functions, the compiler
    does not give warning or error message, what happened?

    Thanks in advance
     
    Chapman, Sep 15, 2003
    #1
    1. Advertising

  2. "Chapman" <> wrote:

    >Some questions about strings: this is the extracted piece of my test code:
    >
    >/** **/
    >
    >char *arry;
    >arry = malloc(30*sizeof(arry));

    You allocate memory to hold 30 pointers-to-character, which is obviously
    not your intention; make this:

    arry = malloc( 30 * sizeof *arry );

    >
    >arry[0] = 'B';
    >arry[1] = 'S';
    >arry[2] = 'c';
    >
    >/** **/
    >
    >The questions are:
    >
    >1. Now does the variable arry contain the null character immediately because
    >of malloc?

    No.

    >
    >2. or I should append '0' at arry[3] ?

    If you intend to use it as a string: yes.

    >(which in fact what I did next, but
    >when testing the compiler without '\0', it worked (??)

    This was just (bad) luck; virtually *anything* could have happened.

    >
    > Because in both cases (whether I append '\0' or not), if I use the
    >functions atoi or any other string functions, the compiler
    > does not give warning or error message, what happened?

    The compiler cannot check something that gets allocated and altered at
    run-time. You have to make sure your strings are '\0'-terminated.

    Regards

    Irrwahn
    --
    Close your eyes and press escape three times.
     
    Irrwahn Grausewitz, Sep 15, 2003
    #2
    1. Advertising

  3. Chapman

    Jeff Guest

    "Chapman" <> wrote in message
    news:il99b.102624$...
    > Some questions about strings: this is the extracted piece of my test code:
    >
    > /** **/
    >
    > char *arry;
    > arry = malloc(30*sizeof(arry));


    If you want to allocate a buffer to hold a string, you should write

    arry = malloc(30); /* This way is correct. "sizeof char" is defined as 1
    byte, you don't need to use sizeof on this */

    or

    arry = malloc(30 * sizeof *arry) /* You should use sizeof on "*arry" (which
    is a single char), not char* (which is a pointer. I think this is not what
    you want, right ? ). Also, don't use "sizeof( variable )" , use "sizeof
    variable" or "sizeof(variable type)" instead. */


    >
    > arry[0] = 'B';
    > arry[1] = 'S';
    > arry[2] = 'c';
    >
    > /** **/
    >
    > The questions are:
    >
    > 1. Now does the variable arry contain the null character immediately

    because
    > of malloc?


    No. If you want to fill all the elements by zero after allocated, you can
    consider "calloc"

    > 2. or I should append '0' at arry[3] ?


    Yes.

    (which in fact what I did next, but
    > when testing the compiler without '\0', it worked (??)
    >


    Don't believe this, you are just lucky.

    > Because in both cases (whether I append '\0' or not), if I use the
    > functions atoi or any other string functions, the compiler
    > does not give warning or error message, what happened?


    Why should it give warning or error ?


    --
    Jeff
    -je6543 at yahoo.com
     
    Jeff, Sep 15, 2003
    #3
  4. Chapman

    John Bode Guest

    "Chapman" <> wrote in message news:<il99b.102624$>...
    > Some questions about strings: this is the extracted piece of my test code:
    >
    > /** **/
    >
    > char *arry;
    > arry = malloc(30*sizeof(arry));


    ITYM

    arry = malloc (30 * sizeof *arry);

    The type of arry is char*; the type of *arry is char.

    >
    > arry[0] = 'B';
    > arry[1] = 'S';
    > arry[2] = 'c';
    >
    > /** **/
    >
    > The questions are:
    >
    > 1. Now does the variable arry contain the null character immediately because
    > of malloc?
    >


    No. malloc() does not initialize the allocated memory to any specific
    value. Assume it contains garbage. If you need the memory to be
    initialized to 0 when allocating it, use calloc().

    > 2. or I should append '0' at arry[3] ? (which in fact what I did next, but
    > when testing the compiler without '\0', it worked (??)


    Luck. The memory you allocated just happened to be zeroed out, but
    you can't rely on that behavior.

    >
    > Because in both cases (whether I append '\0' or not), if I use the
    > functions atoi or any other string functions, the compiler
    > does not give warning or error message, what happened?
    >
    > Thanks in advance


    The string functions will walk through memory starting at the point
    you specify until they see a nul terminator (0). If you forget to put
    a nul terminator in your buffer, the string functions will happily
    read or write past it until they either find one or try to read or
    write a protected or invalid memory address, causing a trap.

    Either way, forgetting to append a nul terminator to a dynamically
    allocated buffer is a condition that only occurs when the program is
    run; your compiler can't warn you about something that it can't
    predict.
     
    John Bode, Sep 15, 2003
    #4
  5. Chapman

    Chapman Guest

    "Jeff" <> wrote in message
    news:bk3upb$15qb$...
    >
    > "Chapman" <> wrote in message
    > news:il99b.102624$...
    > > Some questions about strings: this is the extracted piece of my test

    code:
    > >
    > > /** **/
    > >
    > > char *arry;
    > > arry = malloc(30*sizeof(arry));

    >
    > If you want to allocate a buffer to hold a string, you should write
    >
    > arry = malloc(30); /* This way is correct. "sizeof char" is defined as 1
    > byte, you don't need to use sizeof on this */
    >
    > or
    >
    > arry = malloc(30 * sizeof *arry) /* You should use sizeof on "*arry"

    (which
    > is a single char), not char* (which is a pointer. I think this is not

    what
    > you want, right ? ). Also, don't use "sizeof( variable )" , use "sizeof
    > variable" or "sizeof(variable type)" instead. */
    >

    Thanks for the explanation Jeff.

    > > The questions are:
    > >
    > > 1. Now does the variable arry contain the null character immediately

    > because
    > > of malloc?

    >
    > No. If you want to fill all the elements by zero after allocated, you can
    > consider "calloc"
    >
    > > 2. or I should append '0' at arry[3] ?

    >
    > Yes.
    >
    > (which in fact what I did next, but
    > > when testing the compiler without '\0', it worked (??)
    > >

    >
    > Don't believe this, you are just lucky.


    I could not believe it either, and everytime I run the program without
    appending the '\0', it was alright.
    Something wrong with gcc ? Following the standard, I appended '\0', just
    curious why it happened without warning.
    It is not about being lucky, or probably the function definitions with gcc
    is 'relaxed' about the '\0' ??

    > > Because in both cases (whether I append '\0' or not), if I use the
    > > functions atoi or any other string functions, the compiler
    > > does not give warning or error message, what happened?

    >
    > Why should it give warning or error ?
    >


    It should gave me error when I run it and the string did not have the '\0',
    but it didn't

    > --
    > Jeff
    > -je6543 at yahoo.com
    >
    >
     
    Chapman, Sep 15, 2003
    #5
  6. Chapman

    Malcolm Guest

    "Chapman" <> wrote in message
    >
    > I could not believe it either, and everytime I run the program without
    > appending the '\0', it was alright.
    > Something wrong with gcc ? Following the standard, I appended '\0',
    > just curious why it happened without warning.
    > It is not about being lucky, or probably the function definitions with gcc
    > is 'relaxed' about the '\0' ??
    >

    String functions will generally fail if passed a non-NUL terminated string.

    However it is quite common for garbage memory to contain a lot of zeroes,
    and you must have just hit a zero. It's also possible that your version of
    malloc() zeroes memory, however you can't rely on this behaviour.

    > It should gave me error when I run it and the string did not have the
    > '\0', but it didn't
    >

    The following code is OK

    char *str = calloc(1,100);
    str[0] = 'F';
    str[1] = 'R';
    str[2] = 'E';
    str[3] = 'D';
    printf("%s\n", str);

    This is because calloc() is guaranteed to zero memory.

    The compiler is not clever enough to distinguish between the function
    calloc() and malloc(), and realise that in your case you are setting up a
    string which is not NUL-terminated. This is because C is such a low-level
    language - strings are just handled as arrays of bytes in memory.
     
    Malcolm, Sep 15, 2003
    #6
  7. "Malcolm" <> wrote:

    >
    >"Chapman" <> wrote in message
    >>
    >> I could not believe it either, and everytime I run the program without
    >> appending the '\0', it was alright.
    >> Something wrong with gcc ? Following the standard, I appended '\0',
    >> just curious why it happened without warning.
    >> It is not about being lucky, or probably the function definitions with gcc
    >> is 'relaxed' about the '\0' ??
    >>

    >String functions will generally fail if passed a non-NUL terminated string.

    ^^^^^^^^^^^^^^^^^^^
    Nit-pick: ... will generally invoke undefined behaviour ...

    <SNIP>

    Regards

    Irrwahn
    --
    Close your eyes and press escape three times.
     
    Irrwahn Grausewitz, Sep 15, 2003
    #7
  8. Chapman

    Minti Guest

    "Chapman" <> wrote in message news:<9ml9b.103923$>...
    > "Jeff" <> wrote in message
    > news:bk3upb$15qb$...
    > >
    > > "Chapman" <> wrote in message
    > > news:il99b.102624$...
    > > > Some questions about strings: this is the extracted piece of my test

    > code:
    > > >
    > > > /** **/
    > > >
    > > > char *arry;
    > > > arry = malloc(30*sizeof(arry));

    > >
    > > If you want to allocate a buffer to hold a string, you should write
    > >
    > > arry = malloc(30); /* This way is correct. "sizeof char" is defined as 1
    > > byte, you don't need to use sizeof on this */
    > >
    > > or
    > >
    > > arry = malloc(30 * sizeof *arry) /* You should use sizeof on "*arry"

    > (which
    > > is a single char), not char* (which is a pointer. I think this is not

    > what
    > > you want, right ? ). Also, don't use "sizeof( variable )" , use "sizeof
    > > variable" or "sizeof(variable type)" instead. */
    > >

    > Thanks for the explanation Jeff.
    >
    > > > The questions are:
    > > >
    > > > 1. Now does the variable arry contain the null character immediately

    > because
    > > > of malloc?

    > >
    > > No. If you want to fill all the elements by zero after allocated, you can
    > > consider "calloc"
    > >
    > > > 2. or I should append '0' at arry[3] ?

    > >
    > > Yes.
    > >
    > > (which in fact what I did next, but
    > > > when testing the compiler without '\0', it worked (??)
    > > >

    > >
    > > Don't believe this, you are just lucky.

    >
    > I could not believe it either, and everytime I run the program without
    > appending the '\0', it was alright.
    > Something wrong with gcc ? Following the standard, I appended '\0', just
    > curious why it happened without warning.
    > It is not about being lucky, or probably the function definitions with gcc
    > is 'relaxed' about the '\0' ??
    >
    > > > Because in both cases (whether I append '\0' or not), if I use the
    > > > functions atoi or any other string functions, the compiler
    > > > does not give warning or error message, what happened?

    > >
    > > Why should it give warning or error ?
    > >

    >
    > It should gave me error when I run it and the string did not have the '\0',
    > but it didn't


    You run it on some other platform it would possibly give you an error
    eventhough the chances of having a runtime error are more than those
    of a compile time error. It is as a matter of fact difficult to get to
    know if you are setting or not setting the null character, consider
    this

    while ( some_condition )
    {
    c = getchar();
    malloced_character_array [ i ] = c;
    i += 1;
    }

    During complile time it is quite difficult to determine as to if what
    the user would set the value to be.


    BTW compiler is not supposed to give any error and I think I won't be
    wrong if I could say that the compiler is not supposed to give error
    even for a completly invalid program

    even if you type garbage in your source file, it is quite unreasonable
    but true that a compiler can give you a message of the form of

    "succesfully built".


    HTH


    PS IIRC someone had a website which showed a missile heading back to
    the carrier which shot them in case of program exhibiting a UB, can
    anybody provide that link.

    --

    Imanpreet Singh Arora
    imanpreet_arora AT yahoo DOT co DOT in
     
    Minti, Sep 16, 2003
    #8
  9. Chapman

    Jack Klein Guest

    On Tue, 16 Sep 2003 00:55:30 +0200, Irrwahn Grausewitz
    <> wrote in comp.lang.c:

    > "Malcolm" <> wrote:
    >
    > >
    > >"Chapman" <> wrote in message
    > >>
    > >> I could not believe it either, and everytime I run the program without
    > >> appending the '\0', it was alright.
    > >> Something wrong with gcc ? Following the standard, I appended '\0',
    > >> just curious why it happened without warning.
    > >> It is not about being lucky, or probably the function definitions with gcc
    > >> is 'relaxed' about the '\0' ??
    > >>

    > >String functions will generally fail if passed a non-NUL terminated string.

    > ^^^^^^^^^^^^^^^^^^^
    > Nit-pick: ... will generally invoke undefined behaviour ...

    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    Even more nit pick: will ALWAYS invoke undefined behavior, which
    generally causes a program to fail.

    >
    > <SNIP>
    >
    > Regards
    >
    > Irrwahn


    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
     
    Jack Klein, Sep 16, 2003
    #9
  10. (Minti) wrote:

    <SNIP>
    >
    >BTW compiler is not supposed to give any error and I think I won't be
    >wrong if I could say that the compiler is not supposed to give error
    >even for a completly invalid program
    >
    >even if you type garbage in your source file, it is quite unreasonable
    >but true that a compiler can give you a message of the form of
    >
    >"succesfully built".
    >

    <SNIP>

    Hmm, consider this quote from n843:

    5.1.1.3 Diagnostics

    [#1] A conforming implementation shall produce at least one
    diagnostic message (identified in an implementation-defined
    manner) if a preprocessing translation unit or translation
    unit contains a violation of any syntax rule or constraint,
    even if the behavior is also explicitly specified as
    undefined or implementation-defined. Diagnostic messages
    need not be produced in other circumstances.7)

    [#2] EXAMPLE An implementation shall issue a diagnostic for
    the translation unit:

    char i;
    int i;

    because in those cases where wording in this International
    Standard describes the behavior for a construct as being
    both a constraint error and resulting in undefined behavior,
    the constraint error shall be diagnosed.

    [...]

    Regards

    Irrwahn
    --
    My opinions are not those of my ex-employer.
     
    Irrwahn Grausewitz, Sep 16, 2003
    #10
  11. On Tue, 16 Sep 2003 01:59:45 GMT, in comp.lang.c , Jack Klein
    <> wrote:

    >On Tue, 16 Sep 2003 00:55:30 +0200, Irrwahn Grausewitz
    ><> wrote in comp.lang.c:
    >
    >> "Malcolm" <> wrote:
    >>
    >> >>
    >> >String functions will generally fail if passed a non-NUL terminated string.

    >> ^^^^^^^^^^^^^^^^^^^
    >> Nit-pick: ... will generally invoke undefined behaviour ...

    > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    >Even more nit pick: will ALWAYS invoke undefined behavior, which
    >generally causes a program to fail.


    super nitpick: which MAY cause a program to fail, or alternatively to
    succeed by pure chance some of the time, or to merely seem to succeed
    but in fact to be storing up trouble for later eg when demo'ing to a
    client. The latter pair are in my experience by far the commonest.
    --
    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>
     
    Mark McIntyre, Sep 16, 2003
    #11
  12. Chapman

    Malcolm Guest

    "Mark McIntyre" <> wrote in message
    > super nitpick: which MAY cause a program to fail, or alternatively to
    > succeed by pure chance some of the time, or to merely seem to
    > succeed but in fact to be storing up trouble for later eg when demo'ing
    > to a client. The latter pair are in my experience by far the commonest.
    >

    We're talking about passing a string which is not NUL-terminated to a string
    function, as opposed to passing a string which has been accidentally
    terminated by a NUL (as the OP seemed to be finding).

    A few functions, like strchr(), will succeed in some circumstances. Most,
    like strlen(), will find it very difficult to produce "correct" results.
    strlen() will probably charge through memory until it hits a zero byte,
    which will either result in an incorrect answer or a segmentation fault.
    Most string functions are similar.
    If you have undefined behaviour, and the string functions seem to be working
    OK, it is unlikely that you are passing non-NUL terminated strings to these
    functions, and UB produces the expected results. It is probable that the
    byte following the string happens to be zero.
     
    Malcolm, Sep 16, 2003
    #12
  13. Chapman

    Minti Guest

    Irrwahn Grausewitz <> wrote in message news:<>...
    > (Minti) wrote:
    >
    > <SNIP>
    > >
    > >BTW compiler is not supposed to give any error and I think I won't be
    > >wrong if I could say that the compiler is not supposed to give error
    > >even for a completly invalid program
    > >
    > >even if you type garbage in your source file, it is quite unreasonable
    > >but true that a compiler can give you a message of the form of
    > >
    > >"succesfully built".
    > >

    > <SNIP>
    >
    > Hmm, consider this quote from n843:
    >
    > 5.1.1.3 Diagnostics
    >
    > [#1] A conforming implementation shall produce at least one
    > diagnostic message (identified in an implementation-defined
    > manner) if a preprocessing translation unit or translation
    > unit contains a violation of any syntax rule or constraint,
    > even if the behavior is also explicitly specified as
    > undefined or implementation-defined. Diagnostic messages
    > need not be produced in other circumstances.7)
    >
    > [#2] EXAMPLE An implementation shall issue a diagnostic for
    > the translation unit:
    >
    > char i;
    > int i;
    >
    > because in those cases where wording in this International
    > Standard describes the behavior for a construct as being
    > both a constraint error and resulting in undefined behavior,
    > the constraint error shall be diagnosed.
    >
    > [...]
    >


    Thanks for correction.
     
    Minti, Sep 17, 2003
    #13
  14. Chapman

    Minti Guest

    (Minti) wrote in message news:<>...

    .....
    <snip>

    >
    > PS IIRC someone had a website which showed a missile heading back to
    > the carrier which shot them in case of program exhibiting a UB, can
    > anybody provide that link.


    http://dspace.dial.pipex.com/town/green/gfd34/art/

    --
    Imanpreet Singh Arora
    imanpreet_arora AT yahoo DOT co DOT in
     
    Minti, Sep 19, 2003
    #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. Replies:
    16
    Views:
    7,339
    Mike Schilling
    Oct 12, 2005
  2. Replies:
    5
    Views:
    26,687
    Mike Schilling
    Mar 29, 2006
  3. Brand Bogard

    8 bit character string to 16 bit character string

    Brand Bogard, May 25, 2006, in forum: C Programming
    Replies:
    8
    Views:
    740
    those who know me have no need of my name
    May 28, 2006
  4. semut
    Replies:
    7
    Views:
    321
    Thad Smith
    Dec 5, 2006
  5. Bart Vandewoestyne
    Replies:
    8
    Views:
    740
    Bart Vandewoestyne
    Sep 25, 2012
Loading...

Share This Page