Allocating memory for strings

Discussion in 'C Programming' started by Win Sock, Oct 6, 2007.

  1. Win Sock

    Win Sock Guest

    Hi All,
    somebody told me this morning that the following is leagal.

    char *a = "Hello wrold";

    The memory is automatically allocated on the fly. Is this correct?
     
    Win Sock, Oct 6, 2007
    #1
    1. Advertising

  2. Win Sock

    santosh Guest

    Win Sock wrote:

    > Hi All,
    > somebody told me this morning that the following is leagal.
    >
    > char *a = "Hello wrold";
    >
    > The memory is automatically allocated on the fly. Is this correct?


    The storage for the string is set aside during translation and the
    pointer 'a' is set to point to it's beginning.

    If the pointer is not static and no other pointers point to the string,
    then the string becomes irretrievable when 'a' goes out of scope.
     
    santosh, Oct 6, 2007
    #2
    1. Advertising

  3. On Oct 6, 6:45 pm, Win Sock <> wrote:
    > Hi All,
    > somebody told me this morning that the following is leagal.
    >
    > char *a = "Hello wrold";
    >
    > The memory is automatically allocated on the fly. Is this correct?


    No.

    A string literal like "Hello wrold" works exactly as if you had a
    static array of const char, and got a pointer to that array, cast to
    char* instead of const char*. So

    char *a = "Hello wrold";

    works exactly the same as

    const char secret_array [] = "Hello wrold";
    char *a = (char *) secret_array;
     
    christian.bau, Oct 6, 2007
    #3
  4. Win Sock

    Joe Wright Guest

    Win Sock wrote:
    > Hi All,
    > somebody told me this morning that the following is leagal.
    >
    > char *a = "Hello wrold";
    >
    > The memory is automatically allocated on the fly. Is this correct?
    >

    Not in the sense of malloc() and friends. free(a) is Undefined. The
    constant string "Hello wrold" is placed somewhere in memory as an
    anonymous array of char, the address of which is placed in a.

    Spelling? legal and world.

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Oct 6, 2007
    #4
  5. Win Sock

    Ben Pfaff Guest

    "christian.bau" <> writes:

    > char *a = "Hello wrold";
    >
    > works exactly the same as
    >
    > const char secret_array [] = "Hello wrold";
    > char *a = (char *) secret_array;


    If it's outside any function, yet; otherwise, secret_array must
    be declared static.
    --
    "For those who want to translate C to Pascal, it may be that a lobotomy
    serves your needs better." --M. Ambuhl

    "Here are the steps to create a C-to-Turbo-Pascal translator..." --H. Schildt
     
    Ben Pfaff, Oct 6, 2007
    #5
  6. "christian.bau" <> writes:
    > On Oct 6, 6:45 pm, Win Sock <> wrote:
    >> somebody told me this morning that the following is leagal.
    >>
    >> char *a = "Hello wrold";
    >>
    >> The memory is automatically allocated on the fly. Is this correct?

    >
    > No.
    >
    > A string literal like "Hello wrold" works exactly as if you had a
    > static array of const char, and got a pointer to that array, cast to
    > char* instead of const char*. So
    >
    > char *a = "Hello wrold";
    >
    > works exactly the same as
    >
    > const char secret_array [] = "Hello wrold";
    > char *a = (char *) secret_array;


    Except that string literals aren't const. (Attempting to modify a
    string literal invokes undefined behavior, but only because the
    standard explicitly says so.) It would be better if string literals
    *were* const, but that would have broken existing code back in 1989
    when the ANSI standard first introduced the "const" keyword.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 6, 2007
    #6
  7. Win Sock

    Tor Rustad Guest

    Win Sock wrote:
    > Hi All,
    > somebody told me this morning that the following is leagal.
    >
    > char *a = "Hello wrold";
    >
    > The memory is automatically allocated on the fly. Is this correct?


    String literals may be placed in read-only memory, and it's undefined
    behavior (UB) altering what *a points to. Hence, you should rather use:

    const char *a = "Hello wrold";

    Note that, else the compiler might not catch this error:

    $ cat -n main.c
    1 #include <stdio.h>
    2
    3
    4 int main(void)
    5 {
    6 char *a = "Hello";
    7 const char *b = "Hello";
    8
    9 printf("%s %s\n", a, b);
    10
    11 a[0]='\0';
    12 b[0]='\0';
    13
    14 return 0;
    15 }

    $ gcc -ansi -pedantic -W -Wall main.c
    main.c: In function âmainâ:
    main.c:12: error: assignment of read-only location

    above, there was no warning about the UB at line 11!

    --
    Tor <torust [at] online [dot] no>

    "There are two ways of constructing a software design. One way is to
    make it so simple that there are obviously no deficiencies. And the
    other way is to make it so complicated that there are no obvious
    deficiencies"
     
    Tor Rustad, Oct 6, 2007
    #7
  8. Win Sock

    santosh Guest

    Tor Rustad wrote:

    > Win Sock wrote:
    >> Hi All,
    >> somebody told me this morning that the following is leagal.
    >>
    >> char *a = "Hello wrold";
    >>
    >> The memory is automatically allocated on the fly. Is this correct?

    >
    > String literals may be placed in read-only memory, and it's undefined
    > behavior (UB) altering what *a points to. Hence, you should rather
    > use:
    >
    > const char *a = "Hello wrold";
    >
    > Note that, else the compiler might not catch this error:
    >
    > $ cat -n main.c
    > 1 #include <stdio.h>
    > 2
    > 3
    > 4 int main(void)
    > 5 {
    > 6 char *a = "Hello";
    > 7 const char *b = "Hello";
    > 8
    > 9 printf("%s %s\n", a, b);
    > 10
    > 11 a[0]='\0';
    > 12 b[0]='\0';
    > 13
    > 14 return 0;
    > 15 }
    >
    > $ gcc -ansi -pedantic -W -Wall main.c
    > main.c: In function âmainâ:
    > main.c:12: error: assignment of read-only location
    >
    > above, there was no warning about the UB at line 11!


    Interestingly if the const qualifier is removed, compilation succeeds
    under gcc, but the executable terminates with a segmentation fault.
    This indicates that gcc places the strings in read-only storage.

    On the other hand under the lcc-linux32 compiler nothing unexpected
    happens. Apparently string literals are _not_ placed into read-only
    storage by lcc-linux32.
     
    santosh, Oct 6, 2007
    #8
  9. Win Sock

    Ben Pfaff Guest

    Keith Thompson <> writes:

    > "christian.bau" <> writes:
    >> char *a = "Hello wrold";
    >>
    >> works exactly the same as
    >>
    >> const char secret_array [] = "Hello wrold";
    >> char *a = (char *) secret_array;

    >
    > Except that string literals aren't const. (Attempting to modify a
    > string literal invokes undefined behavior, but only because the
    > standard explicitly says so.)


    I think that's why Christian included the cast to char *. With
    the cast, the effect is the same.
    --
    char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
    ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
    =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
    2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
     
    Ben Pfaff, Oct 6, 2007
    #9
  10. Win Sock

    Tor Rustad Guest

    santosh wrote:

    [...]

    > Interestingly if the const qualifier is removed, compilation succeeds
    > under gcc, but the executable terminates with a segmentation fault.
    > This indicates that gcc places the strings in read-only storage.


    Yes.

    > On the other hand under the lcc-linux32 compiler nothing unexpected
    > happens. Apparently string literals are _not_ placed into read-only
    > storage by lcc-linux32.


    Did you get a warning with lcc-linux32? I don't have the lcc-linux32
    compiler, but it could use the same storage location for those two
    string literals, which I purpose used "Hello" for both.

    So something "unexpected" could still happen.

    Note that splint issue two warnings for the sample code i posted.

    --
    Tor <torust [at] online [dot] no>

    "There are two ways of constructing a software design. One way is to
    make it so simple that there are obviously no deficiencies. And the
    other way is to make it so complicated that there are no obvious
    deficiencies"
     
    Tor Rustad, Oct 6, 2007
    #10
  11. Win Sock

    santosh Guest

    Tor Rustad wrote:

    > santosh wrote:
    >
    > [...]
    >
    >> Interestingly if the const qualifier is removed, compilation succeeds
    >> under gcc, but the executable terminates with a segmentation fault.
    >> This indicates that gcc places the strings in read-only storage.

    >
    > Yes.
    >
    >> On the other hand under the lcc-linux32 compiler nothing unexpected
    >> happens. Apparently string literals are _not_ placed into read-only
    >> storage by lcc-linux32.

    >
    > Did you get a warning with lcc-linux32? I don't have the lcc-linux32
    > compiler, but it could use the same storage location for those two
    > string literals, which I purpose used "Hello" for both.
    >
    > So something "unexpected" could still happen.
    >
    > Note that splint issue two warnings for the sample code i posted.


    Actually for the sake of brevity I omitted to mention that the test
    program was not what you provided, but a similar one I wrote. Below is
    it's source:

    #include <stdio.h>

    int main(void)
    {
    char *a = "Hello ";
    char *b = "world!\n";

    printf("%s%s", a, b);
    *a = *b;
    *b = *(a+2);
    printf("%s%s", a, b);
    return 0;
    }

    $ gcc -Wall -Wextra -ansi -pedantic -o t11_gcc t11.c
    $ ./t11_gcc
    Hello world!
    Segmentation fault
    $

    $ lcc -ansic t11.c
    $ gcc -o t11_lcc t11.o
    [This is needed because lcc-linux32 does not yet do linking]
    $ ./t11_lcc
    Hello world!
    wello lorld!
    $

    This seems to indicate that gcc places the string literals in read-only
    storage while lcc-linux32 doesn't. Both are of course perfectly
    conforming behaviour and the difference in behaviour is merely a QoI
    issue.
     
    santosh, Oct 6, 2007
    #11
  12. Win Sock

    Tor Rustad Guest

    santosh wrote:
    > Tor Rustad wrote:
    >
    >> santosh wrote:
    >>
    >> [...]
    >>
    >>> Interestingly if the const qualifier is removed, compilation succeeds
    >>> under gcc, but the executable terminates with a segmentation fault.
    >>> This indicates that gcc places the strings in read-only storage.

    >> Yes.
    >>
    >>> On the other hand under the lcc-linux32 compiler nothing unexpected
    >>> happens. Apparently string literals are _not_ placed into read-only
    >>> storage by lcc-linux32.

    >> Did you get a warning with lcc-linux32? I don't have the lcc-linux32
    >> compiler, but it could use the same storage location for those two
    >> string literals, which I purpose used "Hello" for both.
    >>
    >> So something "unexpected" could still happen.
    >>
    >> Note that splint issue two warnings for the sample code i posted.

    >
    > Actually for the sake of brevity I omitted to mention that the test
    > program was not what you provided, but a similar one I wrote. Below is
    > it's source:
    >
    > #include <stdio.h>
    >
    > int main(void)
    > {
    > char *a = "Hello ";
    > char *b = "world!\n";
    >
    > printf("%s%s", a, b);
    > *a = *b;
    > *b = *(a+2);
    > printf("%s%s", a, b);
    > return 0;
    > }
    >
    > $ gcc -Wall -Wextra -ansi -pedantic -o t11_gcc t11.c
    > $ ./t11_gcc
    > Hello world!
    > Segmentation fault
    > $
    >
    > $ lcc -ansic t11.c
    > $ gcc -o t11_lcc t11.o
    > [This is needed because lcc-linux32 does not yet do linking]
    > $ ./t11_lcc
    > Hello world!
    > wello lorld!
    > $
    >
    > This seems to indicate that gcc places the string literals in read-only
    > storage while lcc-linux32 doesn't. Both are of course perfectly
    > conforming behaviour and the difference in behaviour is merely a QoI
    > issue.


    Could you try e.g. this:

    char *a = "Hello";
    char *b = "Hello";

    and check if the lcc use the same storage location?

    --
    Tor <torust [at] online [dot] no>

    "There are two ways of constructing a software design. One way is to
    make it so simple that there are obviously no deficiencies. And the
    other way is to make it so complicated that there are no obvious
    deficiencies"
     
    Tor Rustad, Oct 6, 2007
    #12
  13. Win Sock

    santosh Guest

    Tor Rustad wrote:

    > santosh wrote:
    >> Tor Rustad wrote:
    >>
    >>> santosh wrote:
    >>>
    >>> [...]
    >>>
    >>>> Interestingly if the const qualifier is removed, compilation
    >>>> succeeds under gcc, but the executable terminates with a
    >>>> segmentation fault. This indicates that gcc places the strings in
    >>>> read-only storage.
    >>> Yes.
    >>>
    >>>> On the other hand under the lcc-linux32 compiler nothing unexpected
    >>>> happens. Apparently string literals are _not_ placed into read-only
    >>>> storage by lcc-linux32.
    >>> Did you get a warning with lcc-linux32? I don't have the lcc-linux32
    >>> compiler, but it could use the same storage location for those two
    >>> string literals, which I purpose used "Hello" for both.
    >>>
    >>> So something "unexpected" could still happen.
    >>>
    >>> Note that splint issue two warnings for the sample code i posted.

    >>
    >> Actually for the sake of brevity I omitted to mention that the test
    >> program was not what you provided, but a similar one I wrote. Below
    >> is it's source:
    >>
    >> #include <stdio.h>
    >>
    >> int main(void)
    >> {
    >> char *a = "Hello ";
    >> char *b = "world!\n";
    >>
    >> printf("%s%s", a, b);
    >> *a = *b;
    >> *b = *(a+2);
    >> printf("%s%s", a, b);
    >> return 0;
    >> }
    >>
    >> $ gcc -Wall -Wextra -ansi -pedantic -o t11_gcc t11.c
    >> $ ./t11_gcc
    >> Hello world!
    >> Segmentation fault
    >> $
    >>
    >> $ lcc -ansic t11.c
    >> $ gcc -o t11_lcc t11.o
    >> [This is needed because lcc-linux32 does not yet do linking]
    >> $ ./t11_lcc
    >> Hello world!
    >> wello lorld!
    >> $
    >>
    >> This seems to indicate that gcc places the string literals in
    >> read-only storage while lcc-linux32 doesn't. Both are of course
    >> perfectly conforming behaviour and the difference in behaviour is
    >> merely a QoI issue.

    >
    > Could you try e.g. this:
    >
    > char *a = "Hello";
    > char *b = "Hello";
    >
    > and check if the lcc use the same storage location?


    With your changes to the above program, and an additional line of the
    form:

    printf("a = %p\tb = %p\n", (void *)a, (void *)b);

    I get for gcc:

    $ ./t11_gcc
    a = 0x80484e4 b = 0x80484e4
    Segmentation fault
    $

    and for lcc:

    $ ./t11_lcc
    a = 0x80495dc b = 0x80495dc
    HelloHellolellolello
    $

    So the same storage location is being used for both strings by both
    compilers with the difference that gcc seems to be placing them in
    read-only storage while lcc-linux32 places them in modifiable storage.

    Of course since the code invokes undefined behaviour any result
    is "correct."
     
    santosh, Oct 6, 2007
    #13
  14. Win Sock

    Tor Rustad Guest

    santosh wrote:
    > Tor Rustad wrote:


    [...]

    >> Could you try e.g. this:
    >>
    >> char *a = "Hello";
    >> char *b = "Hello";
    >>
    >> and check if the lcc use the same storage location?

    >
    > With your changes to the above program, and an additional line of the
    > form:
    >
    > printf("a = %p\tb = %p\n", (void *)a, (void *)b);
    >
    > I get for gcc:
    >
    > $ ./t11_gcc
    > a = 0x80484e4 b = 0x80484e4
    > Segmentation fault
    > $
    >
    > and for lcc:
    >
    > $ ./t11_lcc
    > a = 0x80495dc b = 0x80495dc
    > HelloHellolellolello
    > $
    >
    > So the same storage location is being used for both strings by both
    > compilers with the difference that gcc seems to be placing them in
    > read-only storage while lcc-linux32 places them in modifiable storage.


    Thanks santosh, I think this last example program illustrate quite well
    to OP the dangers of modifying string literals. The "unexpected" can
    happen, including for the current version of the lcc compiler.

    > Of course since the code invokes undefined behaviour any result
    > is "correct."


    Let us just call the result undefined, like 0/0 is in mathematics. :)

    --
    Tor <torust [at] online [dot] no>

    "There are two ways of constructing a software design. One way is to
    make it so simple that there are obviously no deficiencies. And the
    other way is to make it so complicated that there are no obvious
    deficiencies"
     
    Tor Rustad, Oct 6, 2007
    #14
  15. santosh wrote:
    > Win Sock wrote:
    >
    >> Hi All,
    >> somebody told me this morning that the following is leagal.
    >>
    >> char *a = "Hello wrold";
    >>
    >> The memory is automatically allocated on the fly. Is this correct?

    >
    > The storage for the string is set aside during translation and the
    > pointer 'a' is set to point to it's beginning.
    >
    > If the pointer is not static and no other pointers point to the string,
    > then the string becomes irretrievable when 'a' goes out of scope.
    >


    If the pointer a goes out of scope or is set to a different
    value, the string may *not* be irretrievable. Some compilers
    only store *one* copy of each string literal and uses that
    one copy everywhere the literal appears in the source.

    So it is possible that this literal may be accessed in other
    ways than through pointer a.

    --
    +----------------------------------------------------------------+
    | Charles and Francis Richmond richmond at plano dot net |
    +----------------------------------------------------------------+
     
    Charles Richmond, Oct 7, 2007
    #15
  16. Win Sock

    ¬a\\/b Guest

    In data Sun, 07 Oct 2007 03:14:25 +0530, santosh scrisse:

    >Tor Rustad wrote:
    >
    >> santosh wrote:
    >>> Tor Rustad wrote:
    >>>
    >>>> santosh wrote:
    >>>>
    >>>> [...]
    >>>>
    >>>>> Interestingly if the const qualifier is removed, compilation
    >>>>> succeeds under gcc, but the executable terminates with a
    >>>>> segmentation fault. This indicates that gcc places the strings in
    >>>>> read-only storage.
    >>>> Yes.
    >>>>
    >>>>> On the other hand under the lcc-linux32 compiler nothing unexpected
    >>>>> happens. Apparently string literals are _not_ placed into read-only
    >>>>> storage by lcc-linux32.
    >>>> Did you get a warning with lcc-linux32? I don't have the lcc-linux32
    >>>> compiler, but it could use the same storage location for those two
    >>>> string literals, which I purpose used "Hello" for both.
    >>>>
    >>>> So something "unexpected" could still happen.
    >>>>
    >>>> Note that splint issue two warnings for the sample code i posted.
    >>>
    >>> Actually for the sake of brevity I omitted to mention that the test
    >>> program was not what you provided, but a similar one I wrote. Below
    >>> is it's source:
    >>>
    >>> #include <stdio.h>
    >>>
    >>> int main(void)
    >>> {
    >>> char *a = "Hello ";
    >>> char *b = "world!\n";
    >>>
    >>> printf("%s%s", a, b);
    >>> *a = *b;
    >>> *b = *(a+2);
    >>> printf("%s%s", a, b);
    >>> return 0;
    >>> }
    >>>
    >>> $ gcc -Wall -Wextra -ansi -pedantic -o t11_gcc t11.c
    >>> $ ./t11_gcc
    >>> Hello world!
    >>> Segmentation fault
    >>> $
    >>>
    >>> $ lcc -ansic t11.c
    >>> $ gcc -o t11_lcc t11.o
    >>> [This is needed because lcc-linux32 does not yet do linking]
    >>> $ ./t11_lcc
    >>> Hello world!
    >>> wello lorld!
    >>> $
    >>>
    >>> This seems to indicate that gcc places the string literals in
    >>> read-only storage while lcc-linux32 doesn't. Both are of course
    >>> perfectly conforming behaviour and the difference in behaviour is
    >>> merely a QoI issue.

    >>
    >> Could you try e.g. this:
    >>
    >> char *a = "Hello";
    >> char *b = "Hello";
    >>
    >> and check if the lcc use the same storage location?

    >
    >With your changes to the above program, and an additional line of the
    >form:
    >
    >printf("a = %p\tb = %p\n", (void *)a, (void *)b);
    >
    >I get for gcc:
    >
    >$ ./t11_gcc
    >a = 0x80484e4 b = 0x80484e4
    >Segmentation fault
    >$
    >
    >and for lcc:
    >
    >$ ./t11_lcc
    >a = 0x80495dc b = 0x80495dc
    >HelloHellolellolello
    >$


    how are smart...
    and all this for save 2 unsigned in the memory ("Hello", 0)

    >So the same storage location is being used for both strings by both
    >compilers with the difference that gcc seems to be placing them in
    >read-only storage while lcc-linux32 places them in modifiable storage.
    >
    >Of course since the code invokes undefined behaviour any result
    >is "correct."
     
    ¬a\\/b, Oct 7, 2007
    #16
  17. Win Sock

    Army1987 Guest

    On Sat, 06 Oct 2007 13:07:24 -0700, Keith Thompson wrote:

    > Except that string literals aren't const. (Attempting to modify a
    > string literal invokes undefined behavior, but only because the
    > standard explicitly says so.) It would be better if string literals
    > *were* const, but that would have broken existing code back in 1989
    > when the ANSI standard first introduced the "const" keyword.

    They could have made string literals const while allowing implicit
    conversion of const char * to char *, and make the return type of
    strchr, strstr etc. const char *, as in C++.
    --
    Army1987 (Replace "NOSPAM" with "email")
    A hamburger is better than nothing.
    Nothing is better than eternal happiness.
    Therefore, a hamburger is better than eternal happiness.
     
    Army1987, Oct 7, 2007
    #17
  18. Win Sock

    Jack Klein Guest

    On Sun, 07 Oct 2007 16:35:29 +0200, Army1987 <>
    wrote in comp.lang.c:

    > On Sat, 06 Oct 2007 13:07:24 -0700, Keith Thompson wrote:
    >
    > > Except that string literals aren't const. (Attempting to modify a
    > > string literal invokes undefined behavior, but only because the
    > > standard explicitly says so.) It would be better if string literals
    > > *were* const, but that would have broken existing code back in 1989
    > > when the ANSI standard first introduced the "const" keyword.

    > They could have made string literals const while allowing implicit
    > conversion of const char * to char *, and make the return type of
    > strchr, strstr etc. const char *, as in C++.


    What does that fix? What errors does it prevent that are not
    prevented by making it undefined behavior to attempt to modify string
    literals?

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Oct 8, 2007
    #18
  19. Win Sock

    Army1987 Guest

    On Sun, 07 Oct 2007 21:10:35 -0500, Jack Klein wrote:

    > On Sun, 07 Oct 2007 16:35:29 +0200, Army1987 <>
    > wrote in comp.lang.c:
    >
    >> On Sat, 06 Oct 2007 13:07:24 -0700, Keith Thompson wrote:
    >>
    >> > Except that string literals aren't const. (Attempting to modify a
    >> > string literal invokes undefined behavior, but only because the
    >> > standard explicitly says so.) It would be better if string literals
    >> > *were* const, but that would have broken existing code back in 1989
    >> > when the ANSI standard first introduced the "const" keyword.

    >> They could have made string literals const while allowing implicit
    >> conversion of const char * to char *, and make the return type of
    >> strchr, strstr etc. const char *, as in C++.

    >
    > What does that fix? What errors does it prevent that are not
    > prevented by making it undefined behavior to attempt to modify string
    > literals?

    I don't like the idea of having something I can't write to while
    its type isn't const. Think that in C99
    (const char []){ 'a', 'b', 0 } and "ab" are allowed to be the same
    object. This doesn't sound like a logical choice to me.
    Also, if it is true that I am allowed to modify argv and
    argv[j] but not necessarily argv (an errata to K&R2 says "It
    isn't forbidden, but it isn't allowed either"), I'd prefer it to
    be declared as char *const *argv.

    --
    Army1987 (Replace "NOSPAM" with "email")
    A hamburger is better than nothing.
    Nothing is better than eternal happiness.
    Therefore, a hamburger is better than eternal happiness.
     
    Army1987, Oct 8, 2007
    #19
  20. On Oct 7, 2:44 am, santosh <> wrote:
    > Tor Rustad wrote:
    > > santosh wrote:
    > >> Tor Rustad wrote:

    >
    > >>> santosh wrote:

    >
    > >>> [...]

    >
    > >>>> Interestingly if the const qualifier is removed, compilation
    > >>>> succeeds under gcc, but the executable terminates with a
    > >>>> segmentation fault. This indicates that gcc places the strings in
    > >>>> read-only storage.
    > >>> Yes.

    >
    > >>>> On the other hand under the lcc-linux32 compiler nothing unexpected
    > >>>> happens. Apparently string literals are _not_ placed into read-only
    > >>>> storage by lcc-linux32.
    > >>> Did you get a warning with lcc-linux32? I don't have the lcc-linux32
    > >>> compiler, but it could use the same storage location for those two
    > >>> string literals, which I purpose used "Hello" for both.

    >
    > >>> So something "unexpected" could still happen.

    >
    > >>> Note that splint issue two warnings for the sample code i posted.

    >
    > >> Actually for the sake of brevity I omitted to mention that the test
    > >> program was not what you provided, but a similar one I wrote. Below
    > >> is it's source:

    >
    > >> #include <stdio.h>

    >
    > >> int main(void)
    > >> {
    > >> char *a = "Hello ";
    > >> char *b = "world!\n";

    >
    > >> printf("%s%s", a, b);
    > >> *a = *b;
    > >> *b = *(a+2);
    > >> printf("%s%s", a, b);
    > >> return 0;
    > >> }

    >
    > >> $ gcc -Wall -Wextra -ansi -pedantic -o t11_gcc t11.c
    > >> $ ./t11_gcc
    > >> Hello world!
    > >> Segmentation fault
    > >> $

    >
    > >> $ lcc -ansic t11.c
    > >> $ gcc -o t11_lcc t11.o
    > >> [This is needed because lcc-linux32 does not yet do linking]
    > >> $ ./t11_lcc
    > >> Hello world!
    > >> wello lorld!
    > >> $

    >
    > >> This seems to indicate that gcc places the string literals in
    > >> read-only storage while lcc-linux32 doesn't. Both are of course
    > >> perfectly conforming behaviour and the difference in behaviour is
    > >> merely a QoI issue.

    >
    > > Could you try e.g. this:

    >
    > > char *a = "Hello";
    > > char *b = "Hello";

    >
    > > and check if the lcc use the same storage location?

    >
    > With your changes to the above program, and an additional line of the
    > form:
    >
    > printf("a = %p\tb = %p\n", (void *)a, (void *)b);
    >
    > I get for gcc:
    >
    > $ ./t11_gcc
    > a = 0x80484e4 b = 0x80484e4
    > Segmentation fault
    > $
    >
    > and for lcc:
    >
    > $ ./t11_lcc
    > a = 0x80495dc b = 0x80495dc
    > HelloHellolellolello
    > $
    >
    > So the same storage location is being used for both strings by both
    > compilers with the difference that gcc seems to be placing them in
    > read-only storage while lcc-linux32 places them in modifiable storage.
    >
    > Of course since the code invokes undefined behaviour any result
    > is "correct."- Hide quoted text -
    >
    > - Show quoted text -


    Some compilers have a switch controlling whether string literals are
    writable or not (for compiling old code),
    and some may have options to cause string literals to be formally
    treated as arrays of const char (for better error catching).

    Earlier C didn not have the 'const' keyword, so if you wanted to
    pass a string literal to a particular function( In sucha way that
    the
    string will not be modified inside the function), then that
    particular function must take a 'char*' argument. Thats all.

    Karthik Balaguru
     
    karthikbalaguru, Oct 11, 2007
    #20
    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. hall
    Replies:
    4
    Views:
    445
  2. soni29
    Replies:
    6
    Views:
    412
    Kevin Goodsell
    Sep 5, 2003
  3. Ben

    Strings, Strings and Damned Strings

    Ben, Jun 22, 2006, in forum: C Programming
    Replies:
    14
    Views:
    767
    Malcolm
    Jun 24, 2006
  4. Rakesh Kumar
    Replies:
    5
    Views:
    684
    James Kanze
    Dec 21, 2007
  5. Mike

    Allocating Memory And Strings

    Mike, Feb 28, 2009, in forum: C Programming
    Replies:
    6
    Views:
    487
Loading...

Share This Page